Add new line decals. (#29907)

* Add new line decals.

* undefs

* remove redundant alpha

* fix lint
This commit is contained in:
warriorstar-orion
2025-08-06 06:01:09 +00:00
committed by GitHub
parent d39c12ce5c
commit b5ac86c818
10 changed files with 413 additions and 157 deletions
@@ -1,11 +1,40 @@
/datum/asset/spritesheet/decal_painter
name = "decal_painter"
var/obj/effect/turf_decal/current_typepath
/datum/asset/spritesheet/decal_painter/create_spritesheets()
// The first sprite we insert is a blank 32x32 icon. This means that when we
// generate class names for icon state/direction combinations that don't
// exist, the ones with non-existent class names will instead just point to the
// first image on the sheet.
Insert("blank", 'icons/turf/decals.dmi', "blank")
for(var/obj/effect/turf_decal/decal_type as anything in subtypesof(/obj/effect/turf_decal))
current_typepath = decal_type
var/decal_classname = replace_characters("[decal_type]", list("/" = "_"))
if(decal_type::icon_state == "")
continue
for(var/direction in GLOB.alldirs)
Insert(
"[decal_classname]_[direction]",
decal_type::icon,
decal_type::icon_state,
direction,
)
/datum/asset/spritesheet/decal_painter/ModifyInserted(icon/pre_asset)
var/icon/parent = ..()
if(current_typepath && current_typepath::color)
parent.Blend(current_typepath::color, ICON_MULTIPLY)
return parent
/datum/painter/decal
module_name = "decal painter"
module_state = "decal_painter"
/// icon that contains the decal sprites
var/decal_icon = 'icons/turf/decals.dmi'
/// icon_state of the selected decal
var/decal_state = "warn_box"
var/decal_dir = SOUTH
var/selected_type = /obj/effect/turf_decal/stripes/box
var/selected_dir = SOUTH
var/selected_category = DECAL_PAINTER_CATEGORY_STANDARD
/// When removal_mode is TRUE the decal painter will remove decals instead
var/removal_mode = FALSE
var/max_decals = 3
@@ -18,7 +47,7 @@
/obj/effect/turf_decal/sand
)
)
/// Assoc list with icon_state of the decal as the key, and decal path as the value.
/// List of typepaths of turf decals exposed by the painter.
var/static/list/lookup_cache_decals = list()
/datum/painter/decal/New(obj/item/painter/parent_painter)
@@ -28,7 +57,9 @@
var/obj/effect/turf_decal/decal = D
if(decal in decal_blacklist)
continue
lookup_cache_decals[decal::icon_state] = decal
if(decal::icon_state == "blank")
continue
lookup_cache_decals += decal
/datum/painter/decal/paint_atom(atom/target, mob/user)
if(!istype(target, /turf/simulated/floor))
@@ -42,8 +73,9 @@
if(length(decals) >= max_decals)
to_chat(user, "<span class='warning'>You can't fit more decals on [target].</span>")
return FALSE
var/typepath = lookup_cache_decals[decal_state]
new typepath(target_turf, decal_dir)
if(ispath(selected_type, /obj/effect/turf_decal))
new selected_type(target_turf, selected_dir)
return TRUE
/datum/painter/decal/pick_color(mob/user)
@@ -63,19 +95,39 @@
/datum/painter/decal/ui_data(mob/user)
var/list/data = list()
data["selectedStyle"] = decal_state
data["selectedDir"] = decal_dir
data["selectedDecalType"] = selected_type
data["selectedDir"] = selected_dir
data["selectedCategory"] = selected_category
data["removalMode"] = removal_mode
return data
/datum/painter/decal/ui_static_data(mob/user)
var/list/data = list()
data["icon"] = decal_icon
data["availableStyles"] = list()
for(var/decal in lookup_cache_decals)
data["availableStyles"] += decal
var/static/list/data
if(!data)
data = list()
data["categories"] = list(
DECAL_PAINTER_CATEGORY_STANDARD,
DECAL_PAINTER_CATEGORY_THIN,
DECAL_PAINTER_CATEGORY_THICK,
DECAL_PAINTER_CATEGORY_SQUARE,
DECAL_PAINTER_CATEGORY_ALPHANUM,
)
data["icon"] = decal_icon
var/list/availableStyles = list()
for(var/decal in lookup_cache_decals)
var/obj/effect/turf_decal/decal_type = decal
if(!(decal_type::painter_category in availableStyles))
availableStyles[decal_type::painter_category] = list()
availableStyles[decal_type::painter_category] += list(list(
"icon" = decal_type::icon,
"icon_state" = decal_type::icon_state,
"color" = decal_type::color,
"typepath" = decal_type,
))
data["availableStyles"] = availableStyles
return data
@@ -83,32 +135,29 @@
if(..())
return
if(action == "select_style")
var/new_style = params["style"]
if(lookup_cache_decals.Find(new_style) != 0)
decal_state = new_style
switch(action)
if("set_category")
selected_category = params["category"]
if("set_direction")
var/new_dir = params["direction"]
removal_mode = FALSE
if(new_dir != 0)
selected_dir = new_dir
if("set_decal_type")
var/new_decal_type = text2path(params["decal_type"])
if(ispath(new_decal_type))
selected_type = new_decal_type
removal_mode = FALSE
if("toggle_removal_mode")
removal_mode = !removal_mode
if(action == "cycle_style") // Cycles through the available styles one at a time
var/index = lookup_cache_decals.Find(decal_state) // Find the index of the currently selected style in the lookup cache
index += params["offset"] // Offset is either -1 or 1. Add this to the index to get the style before or after the current style.
if(index < 1) // If the index is below 1, loop back to the last item in the cache.
index = length(lookup_cache_decals)
if(index > length(lookup_cache_decals)) // If the index is above the length of the cache, loop back to the first item in the cache.
index = 1
decal_state = lookup_cache_decals[index] // Then set our state to the index
removal_mode = FALSE
if(action == "select_direction")
var/dir = params["direction"]
removal_mode = FALSE
if(dir != 0)
decal_dir = dir
if(action == "removal_mode")
removal_mode = !removal_mode
return TRUE
/datum/painter/decal/ui_assets(mob/user)
return list(
get_asset_datum(/datum/asset/spritesheet/decal_painter)
)
/datum/painter/decal/proc/remove_decals(atom/target)
var/turf/target_turf = get_turf(target)
var/list/datum/element/decal/decals = target_turf.get_decals()