Paint gun consolidation and crate/locker painting (#21902)

We don't need a million paint guns. Makes it so a single paint gun can
paint whatever you want. Which now also includes crates and lockers.

changes:
- rscadd: "Paint sprayers can now be used on unpainted crates and
lockers to give them a custom appearance."
  - rscadd: "Adds paint sprayers to Hangar Tech lockers."
- qol: "Moves pipe painter functionality to paint sprayers; pipe
painters now just flavor objects on some offsites."
- qol: "Adds paint sprayers to allowed items list for utility
toolbelts."
- imageadd: "Codersprites pipe painter with recolorable paint storage
component indicating current color (used by paint sprayer)."
  - imagedel: "Removes old paint sprayer sprite."
- bugfix: "Removes old runtime caused by targeting turfs w/ paint
sprayers that don't have flooring singletons assigned."

<img width="496" height="505" alt="Screenshot 2026-02-20 142403"
src="https://github.com/user-attachments/assets/152ea63a-4baf-48e5-864e-400caef9efc6"
/>
<img width="515" height="429" alt="Screenshot 2026-02-20 142424"
src="https://github.com/user-attachments/assets/cb05b674-ac4f-4e2f-8f17-9d8654f099ff"
/>
<img width="450" height="102" alt="image"
src="https://github.com/user-attachments/assets/aa6e51b5-a325-4e8c-baf8-21134843fbf2"
/>
This commit is contained in:
Batrachophreno
2026-02-27 01:12:05 +00:00
committed by GitHub
parent e31b9729aa
commit 8e602afb32
16 changed files with 235 additions and 56 deletions
@@ -79,6 +79,9 @@
/// Used by body bags and air bubbles.
var/contains_body = FALSE
/// If its a plain grey closet or crate, you can use the paint sprayer on it ONCE to change its appearance.
var/can_label = FALSE
/obj/structure/closet/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "When closed, a <b>welder</b> could be used to weld the closet shut."
@@ -124,6 +127,10 @@
fill()
if(secure)
verbs += /obj/structure/closet/proc/verb_togglelock
// Only plain grey crates and closets can be repainted. Handle label-ability here so we don't have to deal with a ton of bespoke definition adjustments.
if(icon_state == "crate" || icon_state == "generic")
can_label = TRUE
return mapload ? INITIALIZE_HINT_LATELOAD : INITIALIZE_HINT_NORMAL
/obj/structure/closet/LateInitialize()
@@ -492,8 +499,10 @@
attack_hand(user)
else if(istype(attacking_item,/obj/item/card/id) && secure)
togglelock(user)
else if(istype(attacking_item, /obj/item/paint_sprayer))
return
// Secure locker cutting open stuff.
// Secure locker cutting open stuff.
else if(!opened && secure)
if(!broken && istype(attacking_item,/obj/item/material/twohanded/chainsaw))
var/obj/item/material/twohanded/chainsaw/ChainSawVar = attacking_item
@@ -834,6 +843,21 @@
new /obj/item/stack/material/steel(get_turf(src))
qdel(src)
/obj/structure/closet/proc/paint_container(paint_color)
// Fucking engineering container sprites. Closets and crates handle their main sprite/door naming differently.
var/eng_prefix = findtext(paint_color,"eng_")
if(eng_prefix)
if(istype(src,/obj/structure/closet/crate))
icon_state = paint_color
icon_door = "eng"
else
icon_state = "eng"
icon_door = paint_color
// And back to sanity.
else
icon_state = paint_color
can_label = FALSE
update_icon()
/*
==========================
Contents Scanner
@@ -86,7 +86,6 @@
// Painters
new /obj/item/paint_sprayer(src)
new /obj/item/pipe_painter(src)
// Atmospherics Technician
/obj/structure/closet/secure_closet/atmos_personal
@@ -120,7 +119,6 @@
// Painters
new /obj/item/paint_sprayer(src)
new /obj/item/pipe_painter(src)
// Electrical Supplies
/obj/structure/closet/secure_closet/engineering_electrical
@@ -53,6 +53,7 @@
new /obj/item/storage/belt/utility(src)
new /obj/item/flashlight/marshallingwand(src)
new /obj/item/flashlight/marshallingwand(src)
new /obj/item/paint_sprayer(src)
// Machinist
/obj/structure/closet/secure_closet/machinist