[MIRROR] Soap & clean proc refactor (#10989)

Co-authored-by: Guti <32563288+TheCaramelion@users.noreply.github.com>
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2025-06-02 10:18:12 -07:00
committed by GitHub
parent 6badc27205
commit 4558eaab04
39 changed files with 465 additions and 327 deletions

View File

@@ -65,10 +65,6 @@ var/image/contamination_overlay = image('icons/effects/contamination.dmi')
contaminated = 1 contaminated = 1
add_overlay(contamination_overlay) add_overlay(contamination_overlay)
/obj/item/proc/decontaminate()
contaminated = 0
cut_overlay(contamination_overlay)
/mob/proc/contaminate() /mob/proc/contaminate()
/mob/living/carbon/human/contaminate() /mob/living/carbon/human/contaminate()

View File

@@ -0,0 +1,24 @@
// Cleaning flags
// Different kinds of things that can be cleaned.
// Use these when overriding the wash proc or registering for the clean signals to check if your thing should be cleaned
#define CLEAN_TYPE_BLOOD (1 << 0)
#define CLEAN_TYPE_RUNES (1 << 1)
#define CLEAN_TYPE_FINGERPRINTS (1 << 2)
#define CLEAN_TYPE_BELLY (1 << 3) // Belly contaminants
#define CLEAN_TYPE_FIBERS (1 << 4)
#define CLEAN_TYPE_RADIATION (1 << 5)
#define CLEAN_TYPE_DISEASE (1 << 6)
#define CLEAN_TYPE_WEAK (1 << 7) // Special type, add this flag to make some cleaning processes non-instant.
#define CLEAN_TYPE_PAINT (1 << 8)
/// Cleans decals such as dirt and oil off the floor
#define CLEAN_TYPE_LIGHT_DECAL (1 << 9)
/// Cleans decals such as cobwebs off the floor
#define CLEAN_TYPE_HARD_DECAL (1 << 10)
// Different cleaning methods.
// Use these when calling the wash proc for your cleaning apparatus
#define CLEAN_WASH (CLEAN_TYPE_BLOOD | CLEAN_TYPE_RUNES | CLEAN_TYPE_DISEASE | CLEAN_TYPE_LIGHT_DECAL | CLEAN_TYPE_BELLY)
#define CLEAN_SCRUB (CLEAN_WASH | CLEAN_TYPE_FINGERPRINTS | CLEAN_TYPE_FIBERS | CLEAN_TYPE_PAINT | CLEAN_TYPE_HARD_DECAL)
#define CLEAN_RAD CLEAN_TYPE_RADIATION
#define CLEAN_ALL (ALL & ~CLEAN_TYPE_WEAK)

View File

@@ -615,8 +615,6 @@
#define COMSIG_TURF_IS_WET "check_turf_wet" #define COMSIG_TURF_IS_WET "check_turf_wet"
///(max_strength, immediate, duration_decrease = INFINITY): Returns bool. ///(max_strength, immediate, duration_decrease = INFINITY): Returns bool.
#define COMSIG_TURF_MAKE_DRY "make_turf_try" #define COMSIG_TURF_MAKE_DRY "make_turf_try"
///called on an object to clean it of cleanables. Usualy with soap: (num/strength)
#define COMSIG_COMPONENT_CLEAN_ACT "clean_act"
//Creamed //Creamed

View File

@@ -0,0 +1,2 @@
///Called on an object to "clean it", such as removing blood decals/overlays, etc. The clean types bitfield is sent with it. Return TRUE if any cleaning was necessary and thus performed.
#define COMSIG_COMPONENT_CLEAN_ACT "clean_act"

View File

@@ -83,3 +83,5 @@ GLOBAL_VAR_INIT(magic_appearance_detecting_image, new /image) // appearances are
/// NaN isn't a number, damn it. Infinity is a problem too. /// NaN isn't a number, damn it. Infinity is a problem too.
#define isnum_safe(x) ( isnum((x)) && !isnan((x)) && !isinf((x)) ) #define isnum_safe(x) ( isnum((x)) && !isnan((x)) && !isinf((x)) )
#define ismopable(A) (A && (A.layer <= ABOVE_JUNK_LAYER)) //If something can be cleaned by floor-cleaning devices such as mops or clean bots

View File

@@ -0,0 +1,37 @@
/datum/element/cleaning
/datum/element/cleaning/Attach(datum/target)
. = ..()
if(!ismovable(target))
return ELEMENT_INCOMPATIBLE
RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(clean))
/datum/element/cleaning/Detach(datum/target)
. = ..()
UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
/datum/element/cleaning/proc/clean(datum/source)
SIGNAL_HANDLER
var/atom/movable/AM = source
var/turf/tile = AM.loc
if(!isturf(tile))
return
tile.wash(CLEAN_WASH)
for(var/atom/cleaned as anything in tile)
if(isitem(cleaned))
var/obj/item/cleaned_item = cleaned
if(cleaned_item.w_class <= ITEMSIZE_SMALL)
cleaned_item.wash(CLEAN_SCRUB)
continue
if(istype(cleaned, /obj/effect/decal/cleanable))
var/obj/effect/decal/cleanable/cleaned_decal = cleaned
cleaned_decal.wash(CLEAN_SCRUB)
if(!ishuman(cleaned))
continue
var/mob/living/carbon/human/cleaned_human = cleaned
if(cleaned_human.lying)
cleaned_human.wash(CLEAN_SCRUB)
to_chat(cleaned_human, span_danger("[AM] washes your face!"))

View File

@@ -27,117 +27,6 @@
drop_sound = 'sound/items/drop/device.ogg' drop_sound = 'sound/items/drop/device.ogg'
pickup_sound = 'sound/items/pickup/device.ogg' pickup_sound = 'sound/items/pickup/device.ogg'
/obj/item/soap
name = "soap"
desc = "A cheap bar of soap. Smells of lye."
gender = PLURAL
icon = 'icons/obj/soap.dmi'
icon_state = "soap"
flags = NOCONDUCT
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_HOLSTER
throwforce = 0
throw_speed = 4
throw_range = 20
var/randomize = TRUE
var/square_chance = 10
/obj/item/soap/Initialize(mapload)
if(randomize && prob(square_chance))
icon_state = "[icon_state]-alt"
. = ..()
/obj/item/soap/nanotrasen
desc = "A NanoTrasen-brand bar of soap. Smells of phoron, a years-old marketing gimmick."
icon_state = "soapnt"
/obj/item/soap/deluxe
icon_state = "soapdeluxe"
/obj/item/soap/deluxe/Initialize(mapload)
. = ..()
desc = "A deluxe Waffle Co. brand bar of soap. Smells of [pick("lavender", "vanilla", "strawberry", "chocolate" ,"space")]."
/obj/item/soap/syndie
desc = "An untrustworthy bar of soap. Smells of fear."
icon_state = "soapsyndie"
/obj/item/soap/space_soap
desc = "Smells like hot metal and walnuts."
icon_state = "space_soap"
/obj/item/soap/water_soap
desc = "Smells like chlorine."
icon_state = "water_soap"
/obj/item/soap/fire_soap
desc = "Smells like a campfire."
icon_state = "fire_soap"
/obj/item/soap/rainbow_soap
desc = "Smells sickly sweet."
icon_state = "rainbow_soap"
/obj/item/soap/diamond_soap
desc = "Smells like saffron and vanilla."
icon_state = "diamond_soap"
/obj/item/soap/uranium_soap
desc = "Smells not great... Not terrible."
icon_state = "uranium_soap"
/obj/item/soap/silver_soap
desc = "Smells like birch and amaranth."
icon_state = "silver_soap"
/obj/item/soap/brown_soap
desc = "Smells like cinnamon and cognac."
icon_state = "brown_soap"
/obj/item/soap/white_soap
desc = "Smells like nutmeg and oats."
icon_state = "white_soap"
/obj/item/soap/grey_soap
desc = "Smells like bergamot and lilies."
icon_state = "grey_soap"
/obj/item/soap/pink_soap
desc = "Smells like bubblegum."
icon_state = "pink_soap"
/obj/item/soap/purple_soap
desc = "Smells like lavender."
icon_state = "purple_soap"
/obj/item/soap/blue_soap
desc = "Smells like cardamom."
icon_state = "blue_soap"
/obj/item/soap/cyan_soap
desc = "Smells like bluebells and peaches."
icon_state = "cyan_soap"
/obj/item/soap/green_soap
desc = "Smells like a freshly mowed lawn."
icon_state = "green_soap"
/obj/item/soap/yellow_soap
desc = "Smells like citron and ginger."
icon_state = "yellow_soap"
/obj/item/soap/orange_soap
desc = "Smells like oranges and dark chocolate."
icon_state = "orange_soap"
/obj/item/soap/red_soap
desc = "Smells like cherries."
icon_state = "red_soap"
/obj/item/soap/golden_soap
desc = "Smells like honey."
icon_state = "golden_soap"
/obj/item/bikehorn /obj/item/bikehorn
name = "bike horn" name = "bike horn"
desc = "A horn off of a bicycle." desc = "A horn off of a bicycle."

View File

@@ -439,18 +439,8 @@
. = 1 . = 1
return 1 return 1
/atom/proc/clean_blood()
if(!simulated)
return
fluorescent = 0
src.germ_level = 0
if(istype(blood_DNA, /list))
blood_DNA = null
return TRUE
blood_color = null //chompfixy, cleaning objects saved its future blood color no matter what
/atom/proc/on_rag_wipe(var/obj/item/reagent_containers/glass/rag/R) /atom/proc/on_rag_wipe(var/obj/item/reagent_containers/glass/rag/R)
clean_blood() wash(CLEAN_WASH)
R.reagents.splash(src, 1) R.reagents.splash(src, 1)
/atom/proc/get_global_map_pos() /atom/proc/get_global_map_pos()
@@ -773,7 +763,7 @@ GLOBAL_LIST_EMPTY(icon_dimensions)
GLOB.icon_dimensions[icon_path] = list("width" = my_icon.Width(), "height" = my_icon.Height()) GLOB.icon_dimensions[icon_path] = list("width" = my_icon.Width(), "height" = my_icon.Height())
return GLOB.icon_dimensions[icon_path] return GLOB.icon_dimensions[icon_path]
///Returns the src and all recursive contents as a list. /// Returns the src and all recursive contents as a list.
/atom/proc/get_all_contents(ignore_flag_1) /atom/proc/get_all_contents(ignore_flag_1)
. = list(src) . = list(src)
var/i = 0 var/i = 0
@@ -783,7 +773,7 @@ GLOBAL_LIST_EMPTY(icon_dimensions)
continue continue
. += checked_atom.contents . += checked_atom.contents
///identical to get_all_contents but returns a list of atoms of the type passed in the argument. /// Identical to get_all_contents but returns a list of atoms of the type passed in the argument.
/atom/proc/get_all_contents_type(type) /atom/proc/get_all_contents_type(type)
var/list/processing_list = list(src) var/list/processing_list = list(src)
. = list() . = list()
@@ -805,3 +795,31 @@ GLOBAL_LIST_EMPTY(icon_dimensions)
/atom/proc/extrapolator_act(mob/living/user, obj/item/extrapolator/extrapolator, dry_run = FALSE) /atom/proc/extrapolator_act(mob/living/user, obj/item/extrapolator/extrapolator, dry_run = FALSE)
. = list(EXTRAPOLATOR_RESULT_DISEASES = list()) . = list(EXTRAPOLATOR_RESULT_DISEASES = list())
SEND_SIGNAL(src, COMSIG_ATOM_EXTRAPOLATOR_ACT, user, extrapolator, dry_run, .) SEND_SIGNAL(src, COMSIG_ATOM_EXTRAPOLATOR_ACT, user, extrapolator, dry_run, .)
/**
* Wash this atom
*
* This will clean it off any temporary stuff like blood. Override this in your item to add custom cleaning behavior.
* Returns true if any washing was necessary and thus performed
* Arguments:
* clean_types: any of the CLEAN_ constants
*/
/atom/proc/wash(clean_types)
SHOULD_CALL_PARENT(TRUE)
. = FALSE
if(SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, clean_types))
. = TRUE
// Basically "if has washable coloration"
if(length(atom_colours) >= WASHABLE_COLOUR_PRIORITY && atom_colours[WASHABLE_COLOUR_PRIORITY])
remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
return TRUE
if(istype(blood_DNA, /list))
blood_DNA = null
return TRUE
blood_color = null // CHOMPEdit - PR this upstream at some point
germ_level = 0
fluorescent = 0

View File

@@ -430,15 +430,15 @@ GLOBAL_LIST_EMPTY(suit_cycler_typecache)
if(helmet) if(helmet)
if(radiation_level > 2) if(radiation_level > 2)
helmet.decontaminate() helmet.wash(CLEAN_TYPE_RADIATION)
if(radiation_level > 1) if(radiation_level > 1)
helmet.clean_blood() helmet.wash(CLEAN_SCRUB)
if(suit) if(suit)
if(radiation_level > 2) if(radiation_level > 2)
suit.decontaminate() suit.wash(CLEAN_TYPE_RADIATION)
if(radiation_level > 1) if(radiation_level > 1)
suit.clean_blood() suit.wash(CLEAN_SCRUB)
. = TRUE . = TRUE

View File

@@ -283,11 +283,11 @@
if(i==3) //End of the cycle if(i==3) //End of the cycle
if(!issuperUV) if(!issuperUV)
if(HELMET) if(HELMET)
HELMET.clean_blood() HELMET.wash(CLEAN_SCRUB)
if(SUIT) if(SUIT)
SUIT.clean_blood() SUIT.wash(CLEAN_SCRUB)
if(MASK) if(MASK)
MASK.clean_blood() MASK.wash(CLEAN_SCRUB)
else //It was supercycling, destroy everything else //It was supercycling, destroy everything
if(HELMET) if(HELMET)
HELMET = null HELMET = null

View File

@@ -58,12 +58,12 @@
update_icon() update_icon()
to_chat(usr, "The washing machine starts a cycle.") to_chat(usr, "The washing machine starts a cycle.")
playsound(src, 'sound/items/washingmachine.ogg', 50, 1, 1) playsound(src, 'sound/items/washingmachine.ogg', 50, 1, 1)
sleep(200)
for(var/atom/A in washing)
A.clean_blood()
for(var/obj/item/I in washing) addtimer(CALLBACK(src, PROC_REF(finish_wash)), 2 SECONDS)
I.decontaminate()
/obj/machinery/washing_machine/proc/finish_wash()
for(var/atom/A in washing)
A.wash(CLEAN_ALL)
//Tanning! //Tanning!
for(var/obj/item/stack/hairlesshide/HH in washing) for(var/obj/item/stack/hairlesshide/HH in washing)
@@ -86,17 +86,14 @@
set category = "Object" set category = "Object"
set src in usr.loc set src in usr.loc
sleep(20) if((state in list(1,3,6)) && do_after(usr, 20))
if(state in list(1,3,6))
usr.loc = src.loc usr.loc = src.loc
/obj/machinery/washing_machine/update_icon() /obj/machinery/washing_machine/update_icon()
//VOREStation Edit
cut_overlays() cut_overlays()
icon_state = "wm_[state]" icon_state = "wm_[state]"
if(panel_open) if(panel_open)
add_overlay("panel") add_overlay("panel")
//VOREStation Edit End
/obj/machinery/washing_machine/attackby(obj/item/W as obj, mob/user as mob) /obj/machinery/washing_machine/attackby(obj/item/W as obj, mob/user as mob)
if(state == 2 && washing.len < 1) if(state == 2 && washing.len < 1)

View File

@@ -31,12 +31,12 @@ var/global/list/image/splatter_cache=list()
basecolor = COLOR_LUMINOL basecolor = COLOR_LUMINOL
update_icon() update_icon()
/obj/effect/decal/cleanable/blood/clean_blood() /obj/effect/decal/cleanable/blood/wash(clean_types)
. = ..()
fluorescent = 0 fluorescent = 0
if(invisibility != INVISIBILITY_MAXIMUM) if(invisibility != INVISIBILITY_MAXIMUM)
invisibility = INVISIBILITY_MAXIMUM invisibility = INVISIBILITY_MAXIMUM
amount = 0 amount = 0
..(ignore=1)
/obj/effect/decal/cleanable/blood/Initialize(mapload) /obj/effect/decal/cleanable/blood/Initialize(mapload)
. = ..() . = ..()

View File

@@ -13,6 +13,9 @@ generic_filth = TRUE means when the decal is saved, it will be switched out for
var/age = 0 var/age = 0
var/list/random_icon_states = list() var/list/random_icon_states = list()
///The type of cleaning required to clean the decal, CLEAN_TYPE_LIGHT_DECAL can be cleaned with mops and soap, CLEAN_TYPE_HARD_DECAL can be cleaned by soap, see __DEFINES/cleaning.dm for the others
var/clean_type = CLEAN_TYPE_LIGHT_DECAL
/obj/effect/decal/cleanable/Initialize(mapload, var/_age) /obj/effect/decal/cleanable/Initialize(mapload, var/_age)
if(!isnull(_age)) if(!isnull(_age))
age = _age age = _age
@@ -23,16 +26,17 @@ generic_filth = TRUE means when the decal is saved, it will be switched out for
. = ..() . = ..()
update_icon() update_icon()
/obj/effect/decal/cleanable/wash(clean_types)
. = ..()
if (. || (clean_types & clean_type))
qdel(src)
return TRUE
return .
/obj/effect/decal/cleanable/Destroy() /obj/effect/decal/cleanable/Destroy()
SSpersistence.forget_value(src, /datum/persistent/filth) SSpersistence.forget_value(src, /datum/persistent/filth)
. = ..() . = ..()
/obj/effect/decal/cleanable/clean_blood(var/ignore = 0)
if(!ignore)
qdel(src)
return
..()
/obj/effect/decal/cleanable/Initialize(mapload, _age) /obj/effect/decal/cleanable/Initialize(mapload, _age)
. = ..() . = ..()
if (random_icon_states && length(random_icon_states) > 0) if (random_icon_states && length(random_icon_states) > 0)

View File

@@ -713,11 +713,6 @@ var/list/global/slot_flags_enumeration = list(
M.eye_blurry += rand(3,4) M.eye_blurry += rand(3,4)
return return
/obj/item/clean_blood()
. = ..()
if(blood_overlay)
overlays.Remove(blood_overlay)
/obj/item/reveal_blood() /obj/item/reveal_blood()
if(was_bloodied && !fluorescent) if(was_bloodied && !fluorescent)
fluorescent = 1 fluorescent = 1
@@ -1171,3 +1166,10 @@ Note: This proc can be overwritten to allow for different types of auto-alignmen
transform = animation_matrix transform = animation_matrix
animate(src, alpha = old_alpha, pixel_x = old_x, pixel_y = old_y, transform = old_transform, time = 3, easing = CUBIC_EASING) animate(src, alpha = old_alpha, pixel_x = old_x, pixel_y = old_y, transform = old_transform, time = 3, easing = CUBIC_EASING)
/obj/item/wash(clean_types)
. = ..()
if(cleanname)
name = cleanname
if(cleandesc)
name = cleandesc

View File

@@ -0,0 +1,217 @@
/obj/item/soap
name = "soap"
desc = "A cheap bar of soap. Doesn't smell."
gender = PLURAL
icon = 'icons/obj/soap.dmi'
icon_state = "soap"
flags = NOCONDUCT
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_HOLSTER
throwforce = 0
throw_speed = 4
throw_range = 20
var/randomize = TRUE
var/square_chance = 10
var/cleanspeed = 35
var/uses = 100
/obj/item/soap/Initialize(mapload)
if(randomize && prob(square_chance))
icon_state = "[icon_state]-alt"
create_reagents(5)
wet()
. = ..()
/obj/item/soap/examine(mob/user)
. = ..()
var/max_uses = initial(uses)
var/msg = "It looks like it just came out of the package."
if(uses != max_uses)
var/percentage_left = uses / max_uses
switch(percentage_left)
if(0 to 0.15)
msg = "There's just a tiny bit left of what it used to be, you're not sure it'll last much longer."
if(0.15 to 0.30)
msg = "It's dissolved quite a bit, but there's still some life to it."
if(0.30 to 0.50)
msg = "It's past its prime, but it's definitely still good."
if(0.50 to 0.75)
msg = "It's started to get a little smaller than it used to be, but it'll definitely still last for a while."
else
msg = "It's seen some light use, but it's still pretty fresh."
. += span_notice("[msg]")
/obj/item/soap/proc/wet()
reagents.add_reagent(REAGENT_ID_CLEANER, 5)
/obj/item/soap/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if(isliving(AM))
var/mob/living/M = AM
M.slip("the [src.name]",3)
/obj/item/soap/afterattack(atom/target, mob/user as mob, proximity)
. = ..()
if(!proximity)
return
//I couldn't feasibly fix the overlay bugs caused by cleaning items we are wearing.
//So this is a workaround. This also makes more sense from an IC standpoint. ~Carn
if(user.client && (target in user.client.screen))
to_chat(user, span_warning("You need to take that [target.name] off before cleaning it."))
else if(istype(target,/obj/effect/decal/cleanable))
user.visible_message("[user] begins to scrub \the [target.name] out with [src].", span_warning("You begin to scrub \the [target.name] out with [src]..."))
if(do_after(user, src.cleanspeed, target = target))
to_chat(user, span_notice("You scrub \the [target.name] out."))
qdel(target)
decreaseUses(user)
else if(istype(target,/turf))
user.visible_message("[user] begins to scrub \the [target.name] out with [src].", span_warning("You begin to scrub \the [target.name] out with [src]..."))
if(do_after(user, src.cleanspeed, target = target))
to_chat(user, span_notice("You scrub \the [target.name] clean."))
var/turf/T = target
T.wash(CLEAN_SCRUB)
decreaseUses(user)
else if(ishuman(target) && user.zone_sel.selecting == O_MOUTH)
if(target == user)
var/mob/living/carbon/human/H = user
to_chat(user, span_notice("You take a bite of \the [src] and swallow it."))
reagents.trans_to_holder(H.ingested, 1)
else
user.visible_message(span_danger("\The [user] washes \the [target]'s mouth out with \the [src]!"))
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
decreaseUses(user, 5)
else if(istype(target,/obj/structure/sink))
to_chat(user, span_notice("You wet \the [src] in the sink."))
wet()
else
user.visible_message("[user] begins to clean \the [target.name] with [src]...", span_notice("You begin to clean \the [target.name] with [src]..."))
if(do_after(user, src.cleanspeed, target = target))
target.wash(CLEAN_SCRUB)
decreaseUses(user)
return
/obj/item/soap/proc/decreaseUses(mob/user, var/used_up = 1)
uses -= used_up
if(uses <= 0)
to_chat(user, span_warning("[src] crumbles into tiny bits!"))
qdel(src)
/obj/item/soap/nanotrasen
name = "Soap (Nanotrasen)"
desc = "A NanoTrasen-brand bar of soap. Smells of phoron, a years-old marketing gimmick."
icon_state = "soapnt"
cleanspeed = 28
uses = 300 // Good soap, good soap
/obj/item/soap/deluxe
name = "Soap (Deluxe)"
icon_state = "soapdeluxe"
uses = 150 // Good soap
cleanspeed = 20 // But fast too
/obj/item/soap/deluxe/Initialize(mapload)
. = ..()
desc = "A deluxe Waffle Co. brand bar of soap. Smells of [pick("lavender", "vanilla", "strawberry", "chocolate" ,"space")]."
/obj/item/soap/syndie
name = "Soap (Syndicate)"
desc = "An untrustworthy bar of soap. Smells of fear."
icon_state = "soapsyndie"
cleanspeed = 5 // Nyoom soap
/obj/item/soap/space_soap
name = "Soap (Space)"
desc = "Smells like hot metal and walnuts."
icon_state = "space_soap"
/obj/item/soap/water_soap
name = "Soap (Pool)"
desc = "Smells like chlorine."
icon_state = "water_soap"
/obj/item/soap/fire_soap
name = "Soap (Fire)"
desc = "Smells like a campfire."
icon_state = "fire_soap"
/obj/item/soap/rainbow_soap
name = "Soap (Rainbow)"
desc = "Smells sickly sweet."
icon_state = "rainbow_soap"
/obj/item/soap/diamond_soap
name = "Soap (Diamond)"
desc = "Smells like saffron and vanilla."
icon_state = "diamond_soap"
/obj/item/soap/uranium_soap
name = "Soap (Uranium)"
desc = "Smells not great... Not terrible."
icon_state = "uranium_soap"
/obj/item/soap/silver_soap
name = "Soap (Silver)"
desc = "Smells like birch and amaranth."
icon_state = "silver_soap"
/obj/item/soap/brown_soap
name = "Soap (Brown)"
desc = "Smells like cinnamon and cognac."
icon_state = "brown_soap"
/obj/item/soap/white_soap
name = "Soap (Nutty)"
desc = "Smells like nutmeg and oats."
icon_state = "white_soap"
/obj/item/soap/grey_soap
name = "Soap (Grey)"
desc = "Smells like bergamot and lilies."
icon_state = "grey_soap"
/obj/item/soap/pink_soap
name = "Soap (Gum)"
desc = "Smells like bubblegum."
icon_state = "pink_soap"
/obj/item/soap/purple_soap
name = "Soap (Lavender)"
desc = "Smells like lavender."
icon_state = "purple_soap"
/obj/item/soap/blue_soap
name = "Soap (Blue)"
desc = "Smells like cardamom."
icon_state = "blue_soap"
/obj/item/soap/cyan_soap
name = "Soap (Berries)"
desc = "Smells like bluebells and peaches."
icon_state = "cyan_soap"
/obj/item/soap/green_soap
name = "Soap (Grass)"
desc = "Smells like a freshly mowed lawn."
icon_state = "green_soap"
/obj/item/soap/yellow_soap
name = "Soap (Lemon)"
desc = "Smells like citron and ginger."
icon_state = "yellow_soap"
/obj/item/soap/orange_soap
name = "Soap (Orange)"
desc = "Smells like oranges and dark chocolate."
icon_state = "orange_soap"
/obj/item/soap/red_soap
name = "Soap (Orange)"
desc = "Smells like cherries."
icon_state = "red_soap"
/obj/item/soap/golden_soap
name = "Soap (Honey)"
desc = "Smells like honey."
icon_state = "golden_soap"

View File

@@ -14,56 +14,6 @@
if(isliving(AM)) if(isliving(AM))
var/mob/living/M = AM var/mob/living/M = AM
M.slip("the [src.name]",4) M.slip("the [src.name]",4)
/*
* Soap
*/
/obj/item/soap/Initialize(mapload)
. = ..()
create_reagents(5)
wet()
/obj/item/soap/proc/wet()
reagents.add_reagent(REAGENT_ID_CLEANER, 5)
/obj/item/soap/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if(isliving(AM))
var/mob/living/M = AM
M.slip("the [src.name]",3)
/obj/item/soap/afterattack(atom/target, mob/user as mob, proximity)
if(!proximity) return
//I couldn't feasibly fix the overlay bugs caused by cleaning items we are wearing.
//So this is a workaround. This also makes more sense from an IC standpoint. ~Carn
if(user.client && (target in user.client.screen))
to_chat(user, span_notice("You need to take that [target.name] off before cleaning it."))
else if(istype(target,/obj/effect/decal/cleanable/blood))
to_chat(user, span_notice("You scrub \the [target.name] out."))
target.clean_blood()
return //Blood is a cleanable decal, therefore needs to be accounted for before all cleanable decals.
else if(istype(target,/obj/effect/decal/cleanable))
to_chat(user, span_notice("You scrub \the [target.name] out."))
qdel(target)
else if(istype(target,/turf))
to_chat(user, span_notice("You scrub \the [target.name] clean."))
var/turf/T = target
T.clean(src, user)
else if(istype(target,/obj/structure/sink))
to_chat(user, span_notice("You wet \the [src] in the sink."))
wet()
else
to_chat(user, span_notice("You clean \the [target.name]."))
target.clean_blood(TRUE)
return
//attack_as_weapon
/obj/item/soap/attack(mob/living/target, mob/living/user, var/target_zone)
if(target && user && ishuman(target) && ishuman(user) && !user.incapacitated() && user.zone_sel &&user.zone_sel.selecting == "mouth" )
user.visible_message(span_danger("\The [user] washes \the [target]'s mouth out with soap!"))
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN) //prevent spam
return
..()
/* /*
* Bike Horns * Bike Horns

View File

@@ -34,7 +34,7 @@ GLOBAL_LIST_BOILERPLATE(all_mops, /obj/item/mop)
if(do_after(user, 40)) if(do_after(user, 40))
var/turf/T = get_turf(A) var/turf/T = get_turf(A)
if(T) if(T)
T.clean(src, user) T.wash(CLEAN_SCRUB)
to_chat(user, span_notice("You have finished mopping!")) to_chat(user, span_notice("You have finished mopping!"))
@@ -75,5 +75,5 @@ GLOBAL_LIST_BOILERPLATE(all_mops, /obj/item/mop)
if(do_after(user, 20)) if(do_after(user, 20))
var/turf/T = get_turf(A) var/turf/T = get_turf(A)
if(T) if(T)
T.clean(src, user) T.wash(CLEAN_SCRUB)
to_chat(user, span_notice("You have finished mopping!")) to_chat(user, span_notice("You have finished mopping!"))

View File

@@ -22,7 +22,7 @@
/turf/proc/clean_deploy(atom/source) /turf/proc/clean_deploy(atom/source)
if(source.reagents.has_reagent(REAGENT_ID_WATER, 1)) if(source.reagents.has_reagent(REAGENT_ID_WATER, 1))
clean_blood() wash(CLEAN_SCRUB)
if(istype(src, /turf/simulated)) if(istype(src, /turf/simulated))
var/turf/simulated/T = src var/turf/simulated/T = src
T.dirt = 0 T.dirt = 0

View File

@@ -220,3 +220,16 @@
var/shake_dir = pick(-1, 1) var/shake_dir = pick(-1, 1)
animate(src, transform=turn(matrix(), 8*shake_dir), pixel_x=init_px + 2*shake_dir, time=1) animate(src, transform=turn(matrix(), 8*shake_dir), pixel_x=init_px + 2*shake_dir, time=1)
animate(transform=null, pixel_x=init_px, time=6, easing=ELASTIC_EASING) animate(transform=null, pixel_x=init_px, time=6, easing=ELASTIC_EASING)
/obj/item/wash(clean_types)
. = ..()
if(blood_overlay && clean_types & CLEAN_WASH)
overlays.Remove(blood_overlay)
if(gurgled && clean_types & CLEAN_WASH)
gurgled = FALSE
cut_overlay(gurgled_overlays[gurgled_color])
name = initial(name)
desc = initial(desc)
if(contaminated && clean_types & CLEAN_RAD) // Phoron and stuff, washing machine needed
contaminated = FALSE
cut_overlay(contamination_overlay)

View File

@@ -194,7 +194,7 @@
wash(M) wash(M)
process_heat(M) process_heat(M)
for (var/atom/movable/G in src.loc) for (var/atom/movable/G in src.loc)
G.clean_blood(TRUE) G.wash(CLEAN_SCRUB)
else else
soundloop.stop() soundloop.stop()
@@ -247,7 +247,7 @@
//Yes, showers are super powerful as far as washing goes. //Yes, showers are super powerful as far as washing goes.
/obj/machinery/shower/proc/wash(atom/movable/O as obj|mob) /obj/machinery/shower/proc/do_wash(atom/movable/O as obj|mob)
if(!on) return if(!on) return
if(isliving(O)) if(isliving(O))
@@ -262,7 +262,7 @@
var/remove_amount = M.touching.maximum_volume * M.reagent_permeability() //take off your suit first var/remove_amount = M.touching.maximum_volume * M.reagent_permeability() //take off your suit first
M.touching.remove_any(remove_amount) M.touching.remove_any(remove_amount)
M.clean_blood() M.wash(CLEAN_SCRUB)
reagents.splash(O, 10, min_spill = 0, max_spill = 0) reagents.splash(O, 10, min_spill = 0, max_spill = 0)
@@ -270,7 +270,7 @@
if(!on) return if(!on) return
for(var/atom/movable/AM in loc) for(var/atom/movable/AM in loc)
if(AM.simulated) if(AM.simulated)
wash(AM) do_wash(AM)
if(isliving(AM)) if(isliving(AM))
var/mob/living/L = AM var/mob/living/L = AM
process_heat(L) process_heat(L)
@@ -282,7 +282,7 @@
return return
is_washing = 1 is_washing = 1
var/turf/T = get_turf(src) var/turf/T = get_turf(src)
T.clean(src) T.wash(CLEAN_SCRUB)
addtimer(VARSET_CALLBACK(src, is_washing, 0), 100, TIMER_DELETE_ME) addtimer(VARSET_CALLBACK(src, is_washing, 0), 100, TIMER_DELETE_ME)
/obj/machinery/shower/proc/process_heat(mob/living/M) /obj/machinery/shower/proc/process_heat(mob/living/M)
@@ -548,21 +548,21 @@
var/mob/living/carbon/human/H = user var/mob/living/carbon/human/H = user
H.gunshot_residue = null H.gunshot_residue = null
if(H.gloves) if(H.gloves)
H.gloves.clean_blood() H.gloves.wash(CLEAN_SCRUB)
H.update_inv_gloves() H.update_inv_gloves()
H.gloves.germ_level = 0 H.gloves.germ_level = 0
else else
if(H.r_hand) if(H.r_hand)
H.r_hand.clean_blood() H.r_hand.wash(CLEAN_SCRUB)
if(H.l_hand) if(H.l_hand)
H.l_hand.clean_blood() H.l_hand.wash(CLEAN_SCRUB)
H.bloody_hands = 0 H.bloody_hands = 0
H.germ_level = 0 H.germ_level = 0
H.hand_blood_color = null H.hand_blood_color = null
LAZYCLEARLIST(H.blood_DNA) LAZYCLEARLIST(H.blood_DNA)
H.update_bloodied() H.update_bloodied()
else else
user.clean_blood() user.wash(CLEAN_SCRUB)
for(var/mob/V in viewers(src, null)) for(var/mob/V in viewers(src, null))
V.show_message(span_notice("[user] washes their hands using \the [src].")) V.show_message(span_notice("[user] washes their hands using \the [src]."))
@@ -623,7 +623,7 @@
return return
busy = 0 busy = 0
O.clean_blood() O.wash(CLEAN_SCRUB)
O.water_act(rand(1,10)) O.water_act(rand(1,10))
user.visible_message( \ user.visible_message( \
span_notice("[user] washes \a [I] using \the [src]."), \ span_notice("[user] washes \a [I] using \the [src]."), \

View File

@@ -63,11 +63,6 @@
cut_overlay(wet_overlay) cut_overlay(wet_overlay)
wet_overlay = null wet_overlay = null
/turf/simulated/clean_blood()
for(var/obj/effect/decal/cleanable/blood/B in contents)
B.clean_blood()
..()
/turf/simulated/Initialize(mapload) /turf/simulated/Initialize(mapload)
. = ..() . = ..()
if(istype(loc, /area/chapel)) if(istype(loc, /area/chapel))

View File

@@ -341,20 +341,6 @@
return 1 return 1
return 0 return 0
//expects an atom containing the reagents used to clean the turf
/turf/proc/clean(atom/source, mob/user)
if(source.reagents.has_reagent(REAGENT_ID_WATER, 1) || source.reagents.has_reagent(REAGENT_ID_CLEANER, 1))
clean_blood()
if(istype(src, /turf/simulated))
var/turf/simulated/T = src
T.dirt = 0
for(var/obj/effect/O in src)
if(istype(O,/obj/effect/rune) || istype(O,/obj/effect/decal/cleanable) || istype(O,/obj/effect/overlay))
qdel(O)
else
to_chat(user, span_warning("\The [source] is too dry to wash that."))
source.reagents.trans_to_turf(src, 1, 10) //10 is the multiplier for the reaction effect. probably needed to wet the floor properly.
/turf/proc/update_blood_overlays() /turf/proc/update_blood_overlays()
return return
@@ -521,3 +507,21 @@
H.ingested.trans_to(V, H.ingested.total_volume / 10) H.ingested.trans_to(V, H.ingested.total_volume / 10)
for(var/datum/reagent/R in H.ingested.reagent_list) for(var/datum/reagent/R in H.ingested.reagent_list)
H.ingested.remove_reagent(R, min(R.volume, 10)) H.ingested.remove_reagent(R, min(R.volume, 10))
/**
* Called when this turf is being washed. Washing a turf will also wash any mopable floor decals
*/
/turf/wash(clean_types)
. = ..()
if(istype(src, /turf/simulated))
var/turf/simulated/T = src
T.dirt = 0
for(var/am in src)
if(am == src)
continue
var/atom/movable/movable_content = am
if(!ismopable(movable_content))
continue
movable_content.wash(clean_types)

View File

@@ -33,7 +33,7 @@
return return
// Aurora forensics port. // Aurora forensics port.
/obj/item/clothing/clean_blood() /obj/item/clothing/wash()
. = ..() . = ..()
gunshot_residue = null gunshot_residue = null
@@ -387,7 +387,7 @@
return return
*/ */
/obj/item/clothing/gloves/clean_blood() /obj/item/clothing/gloves/wash()
. = ..() . = ..()
transfer_blood = 0 transfer_blood = 0
update_icon() update_icon()
@@ -742,15 +742,15 @@
if(contaminated) if(contaminated)
add_overlay(contamination_overlay) add_overlay(contamination_overlay)
if(gurgled) //VOREStation Edit Start if(gurgled) //VOREStation Edit Start
decontaminate() wash(CLEAN_ALL)
gurgle_contaminate() //VOREStation Edit End gurgle_contaminate() //VOREStation Edit End
if(ismob(usr)) if(ismob(usr))
var/mob/M = usr var/mob/M = usr
M.update_inv_shoes() M.update_inv_shoes()
/obj/item/clothing/shoes/clean_blood() /obj/item/clothing/shoes/wash()
. = ..()
update_icon() update_icon()
return ..()
// CHOMPEdit Begin - tweaking handle_movement for inshoes steppies // CHOMPEdit Begin - tweaking handle_movement for inshoes steppies
/obj/item/clothing/shoes/proc/handle_movement(var/turf/walking, var/running, var/mob/living/carbon/human/pred) /obj/item/clothing/shoes/proc/handle_movement(var/turf/walking, var/running, var/mob/living/carbon/human/pred)

View File

@@ -125,7 +125,7 @@
return return
/obj/item/reagent_containers/food/drinks/on_rag_wipe(var/obj/item/reagent_containers/glass/rag/R) /obj/item/reagent_containers/food/drinks/on_rag_wipe(var/obj/item/reagent_containers/glass/rag/R)
clean_blood() wash(CLEAN_SCRUB)
/obj/item/reagent_containers/food/drinks/attack_self(mob/user as mob) /obj/item/reagent_containers/food/drinks/attack_self(mob/user as mob)
if(!is_open_container()) if(!is_open_container())

View File

@@ -141,7 +141,7 @@
automatic_custom_emote(AUDIBLE_MESSAGE, "begins to clean up \the [loc]") automatic_custom_emote(AUDIBLE_MESSAGE, "begins to clean up \the [loc]")
if(do_after(src, cleantime * cTimeMult)) if(do_after(src, cleantime * cTimeMult))
if(blood) if(blood)
clean_blood() wash(CLEAN_TYPE_BLOOD)
if(istype(loc, /turf/simulated)) if(istype(loc, /turf/simulated))
var/turf/simulated/T = loc var/turf/simulated/T = loc
T.dirt = 0 T.dirt = 0

View File

@@ -440,14 +440,14 @@
update_inv_handcuffed() update_inv_handcuffed()
// Clears blood overlays // Clears blood overlays
/mob/living/carbon/clean_blood() /mob/living/carbon/wash(clean_types)
. = ..() . = ..()
if(src.r_hand) if(src.r_hand)
src.r_hand.clean_blood() src.r_hand.wash(clean_types)
if(src.l_hand) if(src.l_hand)
src.l_hand.clean_blood() src.l_hand.wash(clean_types)
if(src.back) if(src.back)
if(src.back.clean_blood()) if(src.back.wash(clean_types))
src.update_inv_back(0) src.update_inv_back(0)
if(ishuman(src)) if(ishuman(src))
@@ -474,48 +474,48 @@
washglasses = !(H.wear_mask.flags_inv & HIDEEYES) washglasses = !(H.wear_mask.flags_inv & HIDEEYES)
if(H.head) if(H.head)
if(H.head.clean_blood()) if(H.head.wash(clean_types))
H.update_inv_head() H.update_inv_head()
if(H.wear_suit) if(H.wear_suit)
if(H.wear_suit.clean_blood()) if(H.wear_suit.wash(clean_types))
H.update_inv_wear_suit() H.update_inv_wear_suit()
else if(H.w_uniform) else if(H.w_uniform)
if(H.w_uniform.clean_blood()) if(H.w_uniform.wash(clean_types))
H.update_inv_w_uniform() H.update_inv_w_uniform()
if(H.gloves && washgloves) if(H.gloves && washgloves)
if(H.gloves.clean_blood()) if(H.gloves.wash(clean_types))
H.update_inv_gloves(0) H.update_inv_gloves(0)
if(H.shoes && washshoes) if(H.shoes && washshoes)
if(H.shoes.clean_blood()) if(H.shoes.wash(clean_types))
H.update_inv_shoes(0) H.update_inv_shoes(0)
if(H.wear_mask && washmask) if(H.wear_mask && washmask)
if(H.wear_mask.clean_blood()) if(H.wear_mask.wash(clean_types))
H.update_inv_wear_mask(0) H.update_inv_wear_mask(0)
if(H.glasses && washglasses) if(H.glasses && washglasses)
if(H.glasses.clean_blood()) if(H.glasses.wash(clean_types))
H.update_inv_glasses(0) H.update_inv_glasses(0)
if(H.l_ear && washears) if(H.l_ear && washears)
if(H.l_ear.clean_blood()) if(H.l_ear.wash(clean_types))
H.update_inv_ears(0) H.update_inv_ears(0)
if(H.r_ear && washears) if(H.r_ear && washears)
if(H.r_ear.clean_blood()) if(H.r_ear.wash(clean_types))
H.update_inv_ears(0) H.update_inv_ears(0)
if(H.belt) if(H.belt)
if(H.belt.clean_blood()) if(H.belt.wash(clean_types))
H.update_inv_belt(0) H.update_inv_belt(0)
else else
if(src.wear_mask) //if the mob is not human, it cleans the mask without asking for bitflags if(src.wear_mask) //if the mob is not human, it cleans the mask without asking for bitflags
if(src.wear_mask.clean_blood()) if(src.wear_mask.wash(clean_types))
src.update_inv_wear_mask(0) src.update_inv_wear_mask(0)
/mob/living/carbon/proc/food_preference(var/allergen_type) //RS edit /mob/living/carbon/proc/food_preference(var/allergen_type) //RS edit

View File

@@ -1149,26 +1149,25 @@
return return
return md5(dna.uni_identity) return md5(dna.uni_identity)
/mob/living/carbon/human/clean_blood(var/washshoes) /mob/living/carbon/human/wash(clean_types)
. = ..() . = ..()
gunshot_residue = null gunshot_residue = null
//Always do hands (or whatever's on our hands) //Always do hands (or whatever's on our hands)
if(gloves) if(gloves)
gloves.clean_blood() gloves.wash(clean_types)
update_inv_gloves() update_inv_gloves()
gloves.germ_level = 0 gloves.germ_level = 0
else else
bloody_hands = 0 bloody_hands = 0
germ_level = 0 germ_level = 0
//Sometimes do shoes if asked (or feet if no shoes) if(shoes)
if(washshoes && shoes) shoes.wash(clean_types)
shoes.clean_blood()
update_inv_shoes() update_inv_shoes()
shoes.germ_level = 0 shoes.germ_level = 0
else if(washshoes && (feet_blood_color || LAZYLEN(feet_blood_DNA))) else if(feet_blood_color || LAZYLEN(feet_blood_DNA))
LAZYCLEARLIST(feet_blood_DNA) LAZYCLEARLIST(feet_blood_DNA)
feet_blood_DNA = null feet_blood_DNA = null
feet_blood_color = null feet_blood_color = null

View File

@@ -223,11 +223,11 @@ var/datum/species/shapeshifter/promethean/prometheans
if(istype(T)) if(istype(T))
if(!(H.shoes || (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)))) if(!(H.shoes || (H.wear_suit && (H.wear_suit.body_parts_covered & FEET))))
for(var/obj/O in T) for(var/obj/O in T)
if(O.clean_blood()) if(O.wash(CLEAN_SCRUB))
H.adjust_nutrition(rand(5, 15)) H.adjust_nutrition(rand(5, 15))
if (istype(T, /turf/simulated)) if (istype(T, /turf/simulated))
var/turf/simulated/S = T var/turf/simulated/S = T
if(T.clean_blood()) if(T.wash(CLEAN_SCRUB))
H.adjust_nutrition(rand(10, 20)) H.adjust_nutrition(rand(10, 20))
if(S.dirt > 50) if(S.dirt > 50)
S.dirt = 0 S.dirt = 0
@@ -245,10 +245,10 @@ var/datum/species/shapeshifter/promethean/prometheans
H.adjust_nutrition(rand(3, 10)) H.adjust_nutrition(rand(3, 10))
if(!(H.gloves || (H.wear_suit && (H.wear_suit.body_parts_covered & HANDS)))) if(!(H.gloves || (H.wear_suit && (H.wear_suit.body_parts_covered & HANDS))))
if(H.r_hand) if(H.r_hand)
if(H.r_hand.clean_blood()) if(H.r_hand.wash(CLEAN_SCRUB))
H.adjust_nutrition(rand(5, 15)) H.adjust_nutrition(rand(5, 15))
if(H.l_hand) if(H.l_hand)
if(H.l_hand.clean_blood()) if(H.l_hand.wash(CLEAN_SCRUB))
H.adjust_nutrition(rand(5, 15)) H.adjust_nutrition(rand(5, 15))
/* /*
if(H.head) if(H.head)

View File

@@ -149,33 +149,33 @@
if(istype(T)) if(istype(T))
if(!(H.shoes || (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)))) if(!(H.shoes || (H.wear_suit && (H.wear_suit.body_parts_covered & FEET))))
for(var/obj/O in T) for(var/obj/O in T)
if(O.clean_blood()) if(O.wash(CLEAN_WASH))
H.adjust_nutrition(rand(5, 15)) H.adjust_nutrition(rand(5, 15))
if (istype(T, /turf/simulated)) if (istype(T, /turf/simulated))
var/turf/simulated/S = T var/turf/simulated/S = T
if(T.clean_blood()) if(T.wash(CLEAN_WASH))
H.adjust_nutrition(rand(10, 20)) H.adjust_nutrition(rand(10, 20))
if(S.dirt > 50) if(S.dirt > 50)
S.dirt = 0 S.dirt = 0
H.adjust_nutrition(rand(10, 20)) H.adjust_nutrition(rand(10, 20))
if(H.clean_blood(1)) if(H.wash(CLEAN_WASH))
H.adjust_nutrition(rand(5, 15)) H.adjust_nutrition(rand(5, 15))
if(H.r_hand) if(H.r_hand)
if(H.r_hand.clean_blood()) if(H.r_hand.wash(CLEAN_WASH))
H.adjust_nutrition(rand(5, 15)) H.adjust_nutrition(rand(5, 15))
if(H.l_hand) if(H.l_hand)
if(H.l_hand.clean_blood()) if(H.l_hand.wash(CLEAN_WASH))
H.adjust_nutrition(rand(5, 15)) H.adjust_nutrition(rand(5, 15))
if(H.head) if(H.head)
if(H.head.clean_blood()) if(H.head.wash(CLEAN_WASH))
H.update_inv_head(0) H.update_inv_head(0)
H.adjust_nutrition(rand(5, 15)) H.adjust_nutrition(rand(5, 15))
if(H.wear_suit) if(H.wear_suit)
if(H.wear_suit.clean_blood()) if(H.wear_suit.wash(CLEAN_WASH))
H.update_inv_wear_suit(0) H.update_inv_wear_suit(0)
H.adjust_nutrition(rand(5, 15)) H.adjust_nutrition(rand(5, 15))
if(H.w_uniform) if(H.w_uniform)
if(H.w_uniform.clean_blood()) if(H.w_uniform.wash(CLEAN_WASH))
H.update_inv_w_uniform(0) H.update_inv_w_uniform(0)
H.adjust_nutrition(rand(5, 15)) H.adjust_nutrition(rand(5, 15))

View File

@@ -233,7 +233,7 @@
water.use_charge(5) water.use_charge(5)
var/obj/effect/decal/cleanable/C = locate() in target var/obj/effect/decal/cleanable/C = locate() in target
qdel(C) qdel(C)
target.clean_blood() target.wash(CLEAN_WASH)
busy = 0 busy = 0
//CHOMPADD End //CHOMPADD End
else if(ishuman(target)) else if(ishuman(target))
@@ -264,7 +264,7 @@
to_chat(user, span_notice("You clean \the [target.name].")) to_chat(user, span_notice("You clean \the [target.name]."))
var/obj/effect/decal/cleanable/C = locate() in target var/obj/effect/decal/cleanable/C = locate() in target
qdel(C) qdel(C)
target.clean_blood() target.wash(CLEAN_WASH)
water.use_charge(5) water.use_charge(5)
if(istype(target, /turf/simulated)) if(istype(target, /turf/simulated))
var/turf/simulated/T = target var/turf/simulated/T = target

View File

@@ -61,7 +61,7 @@
if(scrubbing && isturf(loc)) if(scrubbing && isturf(loc))
var/turf/tile = loc var/turf/tile = loc
tile.clean_blood() tile.wash(CLEAN_SCRUB)
if (istype(tile, /turf/simulated)) if (istype(tile, /turf/simulated))
var/turf/simulated/S = tile var/turf/simulated/S = tile
S.dirt = 0 S.dirt = 0
@@ -71,21 +71,21 @@
qdel(A) qdel(A)
else if(istype(A, /obj/item)) else if(istype(A, /obj/item))
var/obj/item/cleaned_item = A var/obj/item/cleaned_item = A
cleaned_item.clean_blood() cleaned_item.wash(CLEAN_SCRUB)
else if(ishuman(A)) else if(ishuman(A))
var/mob/living/carbon/human/cleaned_human = A var/mob/living/carbon/human/cleaned_human = A
if(cleaned_human.lying) if(cleaned_human.lying)
if(cleaned_human.head) if(cleaned_human.head)
cleaned_human.head.clean_blood() cleaned_human.head.wash(CLEAN_SCRUB)
cleaned_human.update_inv_head(0) cleaned_human.update_inv_head(0)
if(cleaned_human.wear_suit) if(cleaned_human.wear_suit)
cleaned_human.wear_suit.clean_blood() cleaned_human.wear_suit.wash(CLEAN_SCRUB)
cleaned_human.update_inv_wear_suit(0) cleaned_human.update_inv_wear_suit(0)
else if(cleaned_human.w_uniform) else if(cleaned_human.w_uniform)
cleaned_human.w_uniform.clean_blood() cleaned_human.w_uniform.wash(CLEAN_SCRUB)
cleaned_human.update_inv_w_uniform(0) cleaned_human.update_inv_w_uniform(0)
if(cleaned_human.shoes) if(cleaned_human.shoes)
cleaned_human.shoes.clean_blood() cleaned_human.shoes.wash(CLEAN_SCRUB)
cleaned_human.update_inv_shoes(0) cleaned_human.update_inv_shoes(0)
cleaned_human.clean_blood(1) cleaned_human.wash(CLEAN_SCRUB)
to_chat(cleaned_human, span_warning("[src] cleans your face!")) to_chat(cleaned_human, span_warning("[src] cleans your face!"))

View File

@@ -253,8 +253,9 @@
unbuckle_mob(buckled_mob) unbuckle_mob(buckled_mob)
unalert_slug(buckled_mob) unalert_slug(buckled_mob)
/obj/effect/slug_glue/clean_blood(var/ignore = 0) //Remove with space cleaner. /obj/effect/slug_glue/wash(clean_types) // Needs proper scrubbing
if(!ignore) . = ..()
if (. || (clean_types & CLEAN_SCRUB))
qdel(src) qdel(src)
return return TRUE
..() return .

View File

@@ -446,7 +446,7 @@
..() ..()
if(iscarbon(M)) if(iscarbon(M))
var/mob/living/carbon/C = M var/mob/living/carbon/C = M
C.clean_blood(TRUE) C.wash(CLEAN_SCRUB)
if(istype(M, /mob/living/simple_mob/vore/aggressive/macrophage)) // Big ouch for viruses if(istype(M, /mob/living/simple_mob/vore/aggressive/macrophage)) // Big ouch for viruses
var/mob/living/simple_mob/macrophage = M var/mob/living/simple_mob/macrophage = M
@@ -454,7 +454,7 @@
/datum/reagent/space_cleaner/touch_obj(var/obj/O) /datum/reagent/space_cleaner/touch_obj(var/obj/O)
..() ..()
O.clean_blood() O.wash(CLEAN_SCRUB)
/datum/reagent/space_cleaner/touch_turf(var/turf/T) /datum/reagent/space_cleaner/touch_turf(var/turf/T)
..() ..()
@@ -462,7 +462,7 @@
if(istype(T, /turf/simulated)) if(istype(T, /turf/simulated))
var/turf/simulated/S = T var/turf/simulated/S = T
S.dirt = 0 S.dirt = 0
T.clean_blood() T.wash(CLEAN_SCRUB)
for(var/obj/effect/O in T) for(var/obj/effect/O in T)
if(istype(O,/obj/effect/rune) || istype(O,/obj/effect/decal/cleanable) || istype(O,/obj/effect/overlay)) if(istype(O,/obj/effect/rune) || istype(O,/obj/effect/decal/cleanable) || istype(O,/obj/effect/overlay))
qdel(O) qdel(O)
@@ -477,32 +477,32 @@
/datum/reagent/space_cleaner/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) /datum/reagent/space_cleaner/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
if(M.r_hand) if(M.r_hand)
M.r_hand.clean_blood() M.r_hand.wash(CLEAN_SCRUB)
if(M.l_hand) if(M.l_hand)
M.l_hand.clean_blood() M.l_hand.wash(CLEAN_SCRUB)
if(M.wear_mask) if(M.wear_mask)
if(M.wear_mask.clean_blood()) if(M.wear_mask.wash(CLEAN_SCRUB))
M.update_inv_wear_mask(0) M.update_inv_wear_mask(0)
if(ishuman(M)) if(ishuman(M))
var/mob/living/carbon/human/H = M var/mob/living/carbon/human/H = M
if(alien == IS_SLIME) if(alien == IS_SLIME)
M.adjustToxLoss(rand(5, 10)) M.adjustToxLoss(rand(5, 10))
if(H.head) if(H.head)
if(H.head.clean_blood()) if(H.head.wash(CLEAN_SCRUB))
H.update_inv_head(0) H.update_inv_head(0)
if(H.wear_suit) if(H.wear_suit)
if(H.wear_suit.clean_blood()) if(H.wear_suit.wash(CLEAN_SCRUB))
H.update_inv_wear_suit(0) H.update_inv_wear_suit(0)
else if(H.w_uniform) else if(H.w_uniform)
if(H.w_uniform.clean_blood()) if(H.w_uniform.wash(CLEAN_SCRUB))
H.update_inv_w_uniform(0) H.update_inv_w_uniform(0)
if(H.shoes) if(H.shoes)
if(H.shoes.clean_blood()) if(H.shoes.wash(CLEAN_SCRUB))
H.update_inv_shoes(0) H.update_inv_shoes(0)
else else
H.clean_blood(1) H.wash(CLEAN_SCRUB)
return return
M.clean_blood() M.wash(CLEAN_SCRUB)
/datum/reagent/space_cleaner/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) /datum/reagent/space_cleaner/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_SLIME) if(alien == IS_SLIME)

View File

@@ -11,9 +11,9 @@
var/list/storage_items = i.return_inv() var/list/storage_items = i.return_inv()
for(var/obj/item/item in storage_items) for(var/obj/item/item in storage_items)
item.decontaminate() item.wash(CLEAN_WASH)
for(var/obj/item/i in src) for(var/obj/item/i in src)
if(istype(i, /obj/item)) if(istype(i, /obj/item))
i.decontaminate() i.wash(CLEAN_WASH)
. = ..() . = ..()

View File

@@ -1490,7 +1490,7 @@
if(istype(I,/obj/item/card/id)) if(istype(I,/obj/item/card/id))
I.gurgle_contaminate(target.contents, target.contamination_flavor, target.contamination_color) I.gurgle_contaminate(target.contents, target.contamination_flavor, target.contamination_color)
if(I.gurgled && target.contaminates) if(I.gurgled && target.contaminates)
I.decontaminate() I.wash(CLEAN_WASH)
I.gurgle_contaminate(target.contents, target.contamination_flavor, target.contamination_color) I.gurgle_contaminate(target.contents, target.contamination_flavor, target.contamination_color)
items_preserved -= content items_preserved -= content
owner.updateVRPanel() owner.updateVRPanel()

View File

@@ -28,7 +28,7 @@ var/list/gurgled_overlays = list(
return FALSE return FALSE
if(gurgled && !(gurgled_color == contamination_color)) if(gurgled && !(gurgled_color == contamination_color))
decontaminate() wash(CLEAN_WASH)
if(!gurgled) if(!gurgled)
gurgled = TRUE gurgled = TRUE
@@ -53,27 +53,13 @@ var/list/gurgled_overlays = list(
else else
return TRUE return TRUE
/obj/item/decontaminate() //Decontaminate the sogginess as well.
..()
gurgled = FALSE
cut_overlay(gurgled_overlays[gurgled_color])
if(cleanname)
name = cleanname
if(cleandesc)
desc = cleandesc
/obj/item/clean_blood() //Make this type of contamination sink washable as well.
..()
if(gurgled)
decontaminate()
/obj/structure/sink/attackby(obj/item/I, mob/user) //Wash the soggy item before it can interact with the sink. /obj/structure/sink/attackby(obj/item/I, mob/user) //Wash the soggy item before it can interact with the sink.
if(istype(I) && I.gurgled) if(istype(I) && I.gurgled)
to_chat(user, span_notice("You start washing [I].")) to_chat(user, span_notice("You start washing [I]."))
busy = TRUE busy = TRUE
if(do_after(user, 40, src)) if(do_after(user, 40, src))
I.clean_blood() I.wash(CLEAN_SCRUB)
user.visible_message(span_notice("[user] washes [I] using [src]."), user.visible_message(span_notice("[user] washes [I] using [src]."),
span_notice("You wash [I] using [src].")) span_notice("You wash [I] using [src]."))
busy = FALSE busy = FALSE

View File

@@ -70,7 +70,7 @@
if(!oldname) if(!oldname)
oldname = cleanname ? cleanname : name oldname = cleanname ? cleanname : name
cleanname = "[d_stage_name] [oldname]" cleanname = "[d_stage_name] [oldname]"
decontaminate() wash(CLEAN_ALL)
if(istype(B)) if(istype(B))
gurgled_color = B.contamination_color //Apply the correct color setting so uncontaminable things can still have the right overlay. gurgled_color = B.contamination_color //Apply the correct color setting so uncontaminable things can still have the right overlay.
gurgle_contaminate(B, B.contamination_flavor, B.contamination_color) gurgle_contaminate(B, B.contamination_flavor, B.contamination_color)

View File

@@ -203,7 +203,7 @@
var/obj/belly/B = output_dest var/obj/belly/B = output_dest
B.owner_adjust_nutrition((T.dirt - 50) / 10) //Max tile dirt is 101. so about 5 nutrition from a disgusting floor, I think that's okay. B.owner_adjust_nutrition((T.dirt - 50) / 10) //Max tile dirt is 101. so about 5 nutrition from a disgusting floor, I think that's okay.
T.dirt = 0 T.dirt = 0
T.clean_blood() T.wash(CLEAN_WASH)
return return
if(!isturf(target.loc)) if(!isturf(target.loc))
return return

View File

@@ -55,6 +55,7 @@
#include "code\__defines\chemistry.dm" #include "code\__defines\chemistry.dm"
#include "code\__defines\chemistry_vr.dm" #include "code\__defines\chemistry_vr.dm"
#include "code\__defines\circuitboard.dm" #include "code\__defines\circuitboard.dm"
#include "code\__defines\cleaning.dm"
#include "code\__defines\cloning.dm" #include "code\__defines\cloning.dm"
#include "code\__defines\clothing.dm" #include "code\__defines\clothing.dm"
#include "code\__defines\color.dm" #include "code\__defines\color.dm"
@@ -197,6 +198,7 @@
#include "code\__defines\dcs\signals\signals_subsystem.dm" #include "code\__defines\dcs\signals\signals_subsystem.dm"
#include "code\__defines\dcs\signals\signals_tgui.dm" #include "code\__defines\dcs\signals\signals_tgui.dm"
#include "code\__defines\dcs\signals\signals_turf.dm" #include "code\__defines\dcs\signals\signals_turf.dm"
#include "code\__defines\dcs\signals\signals_datum\signals_datum.dm"
#include "code\__defines\dcs\signals\signals_mobs\signals_mob_main.dm" #include "code\__defines\dcs\signals\signals_mobs\signals_mob_main.dm"
#include "code\__defines\traits\_traits.dm" #include "code\__defines\traits\_traits.dm"
#include "code\__defines\traits\declarations.dm" #include "code\__defines\traits\declarations.dm"
@@ -601,6 +603,7 @@
#include "code\datums\diseases\advance\symptoms\weight.dm" #include "code\datums\diseases\advance\symptoms\weight.dm"
#include "code\datums\diseases\advance\symptoms\youth.dm" #include "code\datums\diseases\advance\symptoms\youth.dm"
#include "code\datums\elements\_element.dm" #include "code\datums\elements\_element.dm"
#include "code\datums\elements\cleaning.dm"
#include "code\datums\elements\conflict_checking.dm" #include "code\datums\elements\conflict_checking.dm"
#include "code\datums\elements\footstep.dm" #include "code\datums\elements\footstep.dm"
#include "code\datums\elements\footstep_override.dm" #include "code\datums\elements\footstep_override.dm"
@@ -1443,6 +1446,7 @@
#include "code\game\objects\items\sahoc_ch.dm" #include "code\game\objects\items\sahoc_ch.dm"
#include "code\game\objects\items\selectable_item_vr.dm" #include "code\game\objects\items\selectable_item_vr.dm"
#include "code\game\objects\items\shooting_range.dm" #include "code\game\objects\items\shooting_range.dm"
#include "code\game\objects\items\soap.dm"
#include "code\game\objects\items\surplus_voucher_ch.dm" #include "code\game\objects\items\surplus_voucher_ch.dm"
#include "code\game\objects\items\tailoring.dm" #include "code\game\objects\items\tailoring.dm"
#include "code\game\objects\items\trash.dm" #include "code\game\objects\items\trash.dm"