Fixes washing machines sometimes bluespacing crayons (#23385)

* Fix crayon refs not being nulled when opening "empty" washing machines

* all my homies hate magic numbers

* why was this a thing

* all my homies hate using 0|1 as bools

* ever heard of personal space

* `locate()` cleanup

* Spring cleaning

* Remove unused washing machine state

* whoops

* DGamerL review

* Typecache is the way

* Remove extraneous string initialization

* Negative feedback message consistency

* Documentation my beloved
This commit is contained in:
Nathan Winters
2023-12-12 20:25:12 +00:00
committed by GitHub
parent c12519307a
commit 42d25fea27
+130 -141
View File
@@ -1,3 +1,12 @@
#define OPEN_EMPTY 1
#define CLOSED_EMPTY 2
#define OPEN_FULL 3
#define CLOSED_FULL 4
#define RUNNING 5
//#define OPEN_BLOODY 6 is tied to an unused icon state
#define CLOSED_BLOODY 7
#define RUNNING_BLOODY 8
/obj/machinery/washing_machine
name = "washing machine"
desc = "Gets rid of those pesky bloodstains, or your money back!"
@@ -5,21 +14,42 @@
icon_state = "wm_10"
density = TRUE
anchored = TRUE
var/state = 1
//1 = empty, open door
//2 = empty, closed door
//3 = full, open door
//4 = full, closed door
//5 = running
//6 = blood, open door
//7 = blood, closed door
//8 = blood, running
/// Integer ID corresponding to whether the machine can accept more items, is running, will produce gibs, etc.
var/state = OPEN_EMPTY
var/panel = FALSE
//FALSE = closed
//TRUE = open
var/hacked = TRUE //Bleh, screw hacking, let's have it hacked by default.
var/gibs_ready = 0
var/gibs_ready = FALSE
var/obj/crayon
/// Typecache of washable items
var/list/can_be_washed = list(
/obj/item/stack/sheet/hairlesshide,
/obj/item/clothing/under,
/obj/item/clothing/mask,
/obj/item/clothing/head,
/obj/item/clothing/gloves,
/obj/item/clothing/shoes,
/obj/item/clothing/suit,
/obj/item/bedsheet
)
/// Typecache of items that do not fit, overrides the whitelist
var/list/does_not_fit = list(
/obj/item/clothing/under/plasmaman,
/obj/item/clothing/suit/space,
/obj/item/clothing/suit/syndicatefake,
/obj/item/clothing/suit/cyborg_suit,
/obj/item/clothing/suit/bomb_suit,
/obj/item/clothing/suit/armor,
/obj/item/clothing/mask/gas,
/obj/item/clothing/mask/cigarette,
/obj/item/clothing/head/syndicatefake,
/obj/item/clothing/head/helmet,
/obj/item/clothing/gloves/furgloves
)
/obj/machinery/washing_machine/Initialize(mapload)
. = ..()
can_be_washed = typecacheof(can_be_washed)
does_not_fit = typecacheof(does_not_fit)
/obj/machinery/washing_machine/examine(mob/user)
. = ..()
@@ -31,52 +61,51 @@
start(user)
/obj/machinery/washing_machine/proc/start(mob/user)
if(state != 4)
if(state != CLOSED_FULL)
to_chat(user, "<span class='notice'>The washing machine cannot run in this state.</span>")
return
if(locate(/mob,contents))
state = 8
if(locate(/mob) in src)
state = RUNNING_BLOODY
else
state = 5
state = RUNNING
update_icon(UPDATE_ICON_STATE)
sleep(200)
for(var/atom/A in contents)
for(var/atom/A in src)
A.clean_blood()
//Tanning!
for(var/obj/item/stack/sheet/hairlesshide/HH in contents)
var/obj/item/stack/sheet/wetleather/WL = new(src)
WL.amount = HH.amount
for(var/obj/item/stack/sheet/hairlesshide/HH in src)
new /obj/item/stack/sheet/wetleather(src, HH.amount)
qdel(HH)
if(crayon)
var/wash_color
if(istype(crayon,/obj/item/toy/crayon))
if(istype(crayon, /obj/item/toy/crayon))
var/obj/item/toy/crayon/CR = crayon
wash_color = CR.colourName
else if(istype(crayon,/obj/item/stamp))
else if(istype(crayon, /obj/item/stamp))
var/obj/item/stamp/ST = crayon
wash_color = ST.item_color
if(wash_color)
var/new_jumpsuit_icon_state = ""
var/new_jumpsuit_item_state = ""
var/new_jumpsuit_name = ""
var/new_glove_icon_state = ""
var/new_glove_item_state = ""
var/new_glove_name = ""
var/new_bandana_icon_state = ""
var/new_bandana_item_state = ""
var/new_bandana_name = ""
var/new_shoe_icon_state = ""
var/new_shoe_name = ""
var/new_sheet_icon_state = ""
var/new_sheet_name = ""
var/new_sheet_item_state = ""
var/new_softcap_icon_state = ""
var/new_softcap_name = ""
var/new_jumpsuit_icon_state
var/new_jumpsuit_item_state
var/new_jumpsuit_name
var/new_glove_icon_state
var/new_glove_item_state
var/new_glove_name
var/new_bandana_icon_state
var/new_bandana_item_state
var/new_bandana_name
var/new_shoe_icon_state
var/new_shoe_name
var/new_sheet_icon_state
var/new_sheet_name
var/new_sheet_item_state
var/new_softcap_icon_state
var/new_softcap_name
var/new_desc = "The colors are a bit dodgy."
for(var/T in typesof(/obj/item/clothing/under))
var/obj/item/clothing/under/J = new T
@@ -131,7 +160,7 @@
break
qdel(H)
if(new_jumpsuit_icon_state && new_jumpsuit_item_state && new_jumpsuit_name)
for(var/obj/item/clothing/under/J in contents)
for(var/obj/item/clothing/under/J in src)
if(!J.dyeable)
continue
J.item_state = new_jumpsuit_item_state
@@ -140,7 +169,7 @@
J.name = new_jumpsuit_name
J.desc = new_desc
if(new_glove_icon_state && new_glove_item_state && new_glove_name)
for(var/obj/item/clothing/gloves/color/G in contents)
for(var/obj/item/clothing/gloves/color/G in src)
if(!G.dyeable)
continue
G.item_state = new_glove_item_state
@@ -150,19 +179,19 @@
if(!istype(G, /obj/item/clothing/gloves/color/black/thief))
G.desc = new_desc
if(new_shoe_icon_state && new_shoe_name)
for(var/obj/item/clothing/shoes/S in contents)
for(var/obj/item/clothing/shoes/S in src)
if(!S.dyeable)
continue
if(S.chained == 1)
S.chained = 0
if(S.chained)
S.chained = FALSE
S.slowdown = SHOES_SLOWDOWN
new /obj/item/restraints/handcuffs( src )
new /obj/item/restraints/handcuffs(src)
S.icon_state = new_shoe_icon_state
S.item_color = wash_color
S.name = new_shoe_name
S.desc = new_desc
if(new_bandana_icon_state && new_bandana_name)
for(var/obj/item/clothing/mask/bandana/M in contents)
for(var/obj/item/clothing/mask/bandana/M in src)
if(!M.dyeable)
continue
M.item_state = new_bandana_item_state
@@ -171,14 +200,14 @@
M.name = new_bandana_name
M.desc = new_desc
if(new_sheet_icon_state && new_sheet_name)
for(var/obj/item/bedsheet/B in contents)
for(var/obj/item/bedsheet/B in src)
B.icon_state = new_sheet_icon_state
B.item_color = wash_color
B.item_state = new_sheet_item_state
B.name = new_sheet_name
B.desc = new_desc
if(new_softcap_icon_state && new_softcap_name)
for(var/obj/item/clothing/head/soft/H in contents)
for(var/obj/item/clothing/head/soft/H in src)
if(!H.dyeable)
continue
H.icon_state = new_softcap_icon_state
@@ -188,143 +217,103 @@
QDEL_NULL(crayon)
if(locate(/mob,contents))
state = 7
gibs_ready = 1
if(locate(/mob) in src)
state = CLOSED_BLOODY
gibs_ready = TRUE
else
state = 4
state = CLOSED_FULL
update_icon(UPDATE_ICON_STATE)
/obj/machinery/washing_machine/update_icon_state()
icon_state = "wm_[state][panel]"
/obj/machinery/washing_machine/attackby(obj/item/W as obj, mob/user as mob, params)
/obj/machinery/washing_machine/attackby(obj/item/W, mob/user, params)
if(default_unfasten_wrench(user, W))
return
if(istype(W,/obj/item/toy/crayon) ||istype(W,/obj/item/stamp))
if(state in list( 1, 3, 6))
if(istype(W, /obj/item/toy/crayon) || istype(W, /obj/item/stamp))
if(state in list(OPEN_EMPTY, OPEN_FULL))
if(!crayon)
user.drop_item()
crayon = W
crayon.loc = src
crayon.forceMove(src)
update_icon(UPDATE_ICON_STATE)
else
return ..()
else
return ..()
else if(istype(W,/obj/item/grab))
if((state == 1) && hacked)
else if(istype(W, /obj/item/grab))
if(state == OPEN_EMPTY)
var/obj/item/grab/G = W
if(ishuman(G.assailant) && iscorgi(G.affecting))
G.affecting.loc = src
G.affecting.forceMove(src)
qdel(G)
state = 3
state = OPEN_FULL
update_icon(UPDATE_ICON_STATE)
else
return ..()
else if(istype(W,/obj/item/stack/sheet/hairlesshide) || \
istype(W,/obj/item/clothing/under) || \
istype(W,/obj/item/clothing/mask) || \
istype(W,/obj/item/clothing/head) || \
istype(W,/obj/item/clothing/gloves) || \
istype(W,/obj/item/clothing/shoes) || \
istype(W,/obj/item/clothing/suit) || \
istype(W,/obj/item/bedsheet))
//YES, it's hardcoded... saves a var/can_be_washed for every single clothing item.
if(istype(W,/obj/item/clothing/under/plasmaman))
to_chat(user, "This item does not fit.")
return
if(istype(W,/obj/item/clothing/suit/space))
to_chat(user, "This item does not fit.")
return
if(istype(W,/obj/item/clothing/suit/syndicatefake))
to_chat(user, "This item does not fit.")
return
// if(istype(W,/obj/item/clothing/suit/powered))
// to_chat(user, "This item does not fit.")
// return
if(istype(W,/obj/item/clothing/suit/cyborg_suit))
to_chat(user, "This item does not fit.")
return
if(istype(W,/obj/item/clothing/suit/bomb_suit))
to_chat(user, "This item does not fit.")
return
if(istype(W,/obj/item/clothing/suit/armor))
to_chat(user, "This item does not fit.")
return
if(istype(W,/obj/item/clothing/mask/gas))
to_chat(user, "This item does not fit.")
return
if(istype(W,/obj/item/clothing/mask/cigarette))
to_chat(user, "This item does not fit.")
return
if(istype(W,/obj/item/clothing/head/syndicatefake))
to_chat(user, "This item does not fit.")
return
// if(istype(W,/obj/item/clothing/head/powered))
// to_chat(user, "This item does not fit.")
// return
if(istype(W,/obj/item/clothing/head/helmet))
to_chat(user, "This item does not fit.")
return
if(istype(W,/obj/item/clothing/gloves/furgloves))
to_chat(user, "This item does not fit.")
else if(is_type_in_typecache(W, can_be_washed))
if(is_type_in_typecache(W, does_not_fit))
to_chat(user, "<span class='warning'>This item does not fit.</span>")
return
if(istype(W, /obj/item/clothing/gloves/color/black/krav_maga/sec))
to_chat(user, "<span class='warning'>Washing these gloves would fry the electronics!</span>")
return
if(W.flags & NODROP) //if "can't drop" item
to_chat(user, "<span class='notice'>\The [W] is stuck to your hand, you cannot put it in the washing machine!</span>")
if(W.flags & NODROP)
to_chat(user, "<span class='warning'>[W] is stuck to your hand!</span>")
return
if(contents.len < 5)
if(state in list(1, 3))
if(length(contents) < 5)
if(state in list(OPEN_EMPTY, OPEN_FULL))
user.drop_item()
W.loc = src
state = 3
W.forceMove(src)
state = OPEN_FULL
else
to_chat(user, "<span class='notice'>You can't put the item in right now.</span>")
to_chat(user, "<span class='warning'>The door is closed!</span>")
else
to_chat(user, "<span class='notice'>The washing machine is full.</span>")
to_chat(user, "<span class='warning'>[src] is full!</span>")
update_icon(UPDATE_ICON_STATE)
else
return ..()
/obj/machinery/washing_machine/attack_hand(mob/user as mob)
/obj/machinery/washing_machine/attack_hand(mob/user)
switch(state)
if(1)
state = 2
if(2)
state = 1
for(var/atom/movable/O in contents)
O.loc = src.loc
if(3)
state = 4
if(4)
state = 3
for(var/atom/movable/O in contents)
O.loc = src.loc
if(OPEN_EMPTY)
state = CLOSED_EMPTY
if(CLOSED_EMPTY)
for(var/atom/movable/O in src)
O.forceMove(loc)
crayon = null
state = 1
if(5)
state = OPEN_EMPTY
if(OPEN_FULL)
state = CLOSED_FULL
if(CLOSED_FULL)
for(var/atom/movable/O in src)
O.forceMove(loc)
crayon = null
state = OPEN_EMPTY
if(RUNNING)
to_chat(user, "<span class='warning'>[src] is busy.</span>")
if(6)
state = 7
if(7)
if(CLOSED_BLOODY)
if(gibs_ready)
gibs_ready = 0
if(locate(/mob,contents))
var/mob/M = locate(/mob,contents)
gibs_ready = FALSE
if(locate(/mob) in src)
var/mob/M = locate() in src
M.gib()
for(var/atom/movable/O in contents)
O.loc = src.loc
for(var/atom/movable/O in src)
O.forceMove(loc)
crayon = null
state = 1
state = OPEN_EMPTY
update_icon(UPDATE_ICON_STATE)
/obj/machinery/washing_machine/deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/metal(drop_location(), 2)
qdel(src)
#undef OPEN_EMPTY
#undef CLOSED_EMPTY
#undef OPEN_FULL
#undef CLOSED_FULL
#undef RUNNING
#undef CLOSED_BLOODY
#undef RUNNING_BLOODY