Files
Robwo 19c2327893 I promise It's Not Wallening™ + New Tile Variations (#5169)
## About The Pull Request

As the second half of
https://github.com/Bubberstation/Bubberstation/pull/4918, this pr is
apart of my effort to comprehensively resprite many common assets to be
more cohesive in style and whatnot.

The extra tile variations are just thrown in for more mapper freedom.
They're not deserving of an entire pr dedicated to them.

## Why It's Good For The Game

Skyrat's walls and windows are for the most part ripped from other
codebases. While they have done a serviceable job, their implementation
is not all encompassing and many variations of the standard
walls/windows they intend to replace are simply not accounted for
(namely indestructible variants).

Not to mention, with walls specifically, what has been implemented is
incredibly tedious to modify as they do not use automated icon cutting.
Instead, the dmi is manually built and false wall variations are added
to them.

On top of replacing almost every wall and window tile, walls that were
previously bereft of icon smoothing, now have the capability to do said
smoothing.

Also it's not wallening™.

## Proof Of Testing

<details>
<summary>Screenshots/Videos</summary>
<img width="2304" height="1600" alt="image"
src="https://github.com/user-attachments/assets/94c3ef7b-d754-4754-aac1-4ac36cc81086"
/>

The tile variations: 
<img width="1216" height="896" alt="image"
src="https://github.com/user-attachments/assets/cbc6707e-5258-4cbc-9a79-befaea5efb4e"
/>

<details>
<summary>Contextual Examples</summary>

**Station**
<img width="1216" height="960" alt="image"
src="https://github.com/user-attachments/assets/98357cc3-0b2b-4da4-b148-0aa8005b7efd"
/>
<img width="1216" height="960" alt="image"
src="https://github.com/user-attachments/assets/bef30efd-ae88-49f3-b706-fe34d1df97a7"
/>
<img width="1216" height="960" alt="image"
src="https://github.com/user-attachments/assets/933786f6-a6f8-4fab-b222-fbcef88a440f"
/>

**Centcom**
<img width="1216" height="960" alt="image"
src="https://github.com/user-attachments/assets/7c92c645-4fdb-4e05-91c3-100508fcf0da"
/>

**Shuttle**
<img width="1216" height="896" alt="image"
src="https://github.com/user-attachments/assets/3304c842-8bac-40b0-8024-7c6616717331"
/>

**Plastitanium**
<img width="1088" height="576" alt="image"
src="https://github.com/user-attachments/assets/cb252aab-b501-4218-bd0d-ab60492676a4"
/>
<img width="448" height="704" alt="image"
src="https://github.com/user-attachments/assets/434bceb2-4884-4d2a-826b-b524ec054a56"
/>

**Necropolis**
<img width="1216" height="960" alt="image"
src="https://github.com/user-attachments/assets/aed42870-c4a4-4255-9ff0-7544127469f5"
/>

**Assorted With Notes**

<img width="1216" height="704" alt="image"
src="https://github.com/user-attachments/assets/01f826ee-ca4d-44dc-bc9f-9057f71cb9ea"
/>
Many variations of wall replacements were not previously accounted for.
The most immediate one I could think of were the indestructible wooden
walls in the Ghost Cafe.


<img width="1216" height="960" alt="image"
src="https://github.com/user-attachments/assets/1ad067c3-840c-4f78-a24d-b597dfc34743"
/>
<img width="1216" height="960" alt="image"
src="https://github.com/user-attachments/assets/d0f44e35-46fe-4c38-865c-c3421a2c2282"
/>
The "interior" of many of the wall sprites were kept intentionally flat
and dark as to more convincingly sell perspective*.


<img width="382" height="318" alt="dreamseeker_Cy4kIapjp6"
src="https://github.com/user-attachments/assets/fa5bd972-4a44-4eef-9faf-8992a768f144"
/>

The standard walls are an exception to this rule as they need to be
readily apparent to unscrupulous ne'er-do-wells with mesons.

</details>
</details>

## Changelog

🆑 Robwo
add: Added new variations to small tiles and pod floors
image: Almost all of the wall and window sprites have been redone
image: The palette of wooden platforms now more closely match wooden
floors
image: New bronze table sprites
fix: Fixed rock wall sprites being incorrectly (un)colored
fix: Decal painter now sprays our override decals.
/🆑

---------

Co-authored-by: The Sharkening <95130227+StrangeWeirdKitten@users.noreply.github.com>
2026-05-12 00:09:07 +02:00

162 lines
5.6 KiB
Plaintext

/obj/item/airlock_painter/decal
name = "decal painter"
desc = "An airlock painter, reprogrammed to use a different style of paint in order to apply decals for floor tiles as well, in addition to repainting doors. Decals break when the floor tiles are removed."
desc_controls = "Alt-Click to remove the ink cartridge."
icon = 'icons/obj/devices/tool.dmi'
icon_state = "decal_sprayer"
inhand_icon_state = "decal_sprayer"
custom_materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT * 0.5, /datum/material/glass = SMALL_MATERIAL_AMOUNT * 0.5)
initial_ink_type = /obj/item/toner/large
/// The current direction of the decal being printed
VAR_PRIVATE/selected_dir = SOUTH
/// The current color of the decal being printed.
VAR_PRIVATE/selected_color = "yellow"
/// The current base icon state of the decal being printed.
VAR_PRIVATE/selected_decal_icon_state = "warningline"
/// Current custom color
var/selected_custom_color
/// Current active decal category. Reference to a global singleton
VAR_PRIVATE/datum/paintable_decal_category/current_category
/obj/item/airlock_painter/decal/Initialize(mapload)
. = ..()
set_category(GLOB.paintable_decals[1])
/obj/item/airlock_painter/decal/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
if(isfloorturf(interacting_with) && use_paint(user))
paint_floor(interacting_with)
return ITEM_INTERACT_SUCCESS
return NONE
/**
* Actually add current decal to the floor.
*
* Responsible for actually adding the element to the turf for maximum flexibility.area
* Can be overridden for different decal behaviors.
* Arguments:
* * target - The turf being painted to
*/
/obj/item/airlock_painter/decal/proc/paint_floor(turf/open/floor/target)
var/list/decal_data = current_category.get_decal_info(
state = selected_decal_icon_state,
color = selected_color,
dir = selected_dir,
)
// BUBBER EDIT: overriden with our own decal icons. I hate it but it's what we must do.
target.AddElement( \
/datum/element/decal, \
_icon = 'modular_zubbers/icons/turf/decals/decals.dmi', \
_icon_state = decal_data[DECAL_INFO_ICON_STATE], \
_dir = decal_data[DECAL_INFO_DIR], \
_alpha = decal_data[DECAL_INFO_ALPHA], \
_color = decal_data[DECAL_INFO_COLOR], \
_cleanable = FALSE, \
)
/obj/item/airlock_painter/decal/proc/set_category(datum/paintable_decal_category/category)
current_category = category
selected_color = category.possible_colors?[category.possible_colors[1]]
selected_decal_icon_state = category.get_ui_data()["decal_list"][1]["icon_state"]
return TRUE
/obj/item/airlock_painter/decal/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "DecalPainter", name)
ui.open()
/obj/item/airlock_painter/decal/ui_assets(mob/user)
. = ..()
. += get_asset_datum(/datum/asset/spritesheet_batched/decals)
/obj/item/airlock_painter/decal/ui_static_data(mob/user)
var/list/data = list()
data["categories"] = list()
for(var/datum/paintable_decal_category/category as anything in GLOB.paintable_decals)
var/list/category_data = category.get_ui_data()
data["categories"] += list(list(
"category" = category.category,
"decal_list" = category_data["decal_list"],
"color_list" = category_data["color_list"],
"dir_list" = category_data["dir_list"],
))
var/datum/asset/spritesheet_batched/icon_assets = get_asset_datum(/datum/asset/spritesheet_batched/decals)
data["icon_prefix"] = "[icon_assets.name]32x32"
return data
/obj/item/airlock_painter/decal/ui_data(mob/user)
var/list/data = list()
data["current_decal"] = selected_decal_icon_state
data["current_color"] = selected_color
data["current_dir"] = selected_dir
data["current_custom_color"] = selected_custom_color
data["active_category"] = current_category.category
return data
/obj/item/airlock_painter/decal/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
switch(action)
if("select_category")
var/new_category = params["category"]
for(var/datum/paintable_decal_category/category as anything in GLOB.paintable_decals)
if(category.category != new_category)
continue
set_category(category)
return TRUE
if("select_decal")
var/new_state = params["decal"]
var/new_dir = text2num(params["dir"])
if(current_category.is_state_valid(new_state))
selected_decal_icon_state = new_state
if(current_category.is_dir_valid(new_dir))
selected_dir = new_dir
return TRUE
if("select_color")
var/new_color = params["color"]
if(current_category.is_color_valid(new_color))
selected_color = new_color
return TRUE
if("pick_custom_color")
if("Custom" in current_category.possible_colors)
pick_painting_tool_color(usr, selected_custom_color)
return TRUE
/obj/item/airlock_painter/decal/set_painting_tool_color(chosen_color)
. = ..()
selected_custom_color = chosen_color
selected_color = chosen_color
/obj/item/airlock_painter/decal/debug
name = "extreme decal painter"
icon_state = "decal_sprayer_ex"
initial_ink_type = /obj/item/toner/extreme
/obj/item/airlock_painter/decal/cyborg
icon_state = "decal_sprayer_borg"
initial_ink_type = /obj/item/toner/infinite
/obj/item/airlock_painter/decal/cyborg/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
. = ..()
var/mob/living/silicon/robot/cyborg = user
if(!iscyborg(user) || !cyborg.cell)
return
if(cyborg.cell && cyborg.cell.charge > 0)
cyborg.cell.use(0.025 * STANDARD_CELL_CHARGE)
else if(cyborg.cell.charge <= 0)
balloon_alert(user, "not enough energy!")
return
/obj/item/airlock_painter/decal/cyborg/click_alt(mob/user)
return CLICK_ACTION_BLOCKING