mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-26 06:29:23 +01:00
- Damp rag is now no longer god's perfect cleaning tool. After blood, the damp rag will collect it, and after cleaning a lot of blood, you can no longer clean with the rag until you wash it in a sink (or with cleaner or however you want) - This means the rag will collect DNA in it as you clean, which gives detectives an opportunity to investigate. - It also means the DNA it collects will occasionally spread onto you, meaning you will have to clean your gloves or hands. - Cleaning vomit and such is (currently) unaffected (and does not dirty the rag). - Diseases are not currently transferred to the rag (but this would be fun to add) - Gauze now gets dirty when using it to wrap bleeding wounds. This is just visual, though blood DNA gets transferred. It can be washed in a sink. - Removed gauze on sink / cloth on sink interaction. - Can't really wash gauze with it, plus it's redundant. - Damp rag is no longer a cup. Damp rag is just "soap without any downsides", which is kinda lame. I thought about going a step further and making it require you wet it first but then it just becomes "mop but small" which is also lame. Instead, you're required to clean it, which gives janitors / crewmembers an alternate cleaning method: - Soap: Small, finite, limited. Can't be replenished. - Cleaner: Small, finite, even more limited, ranged. Can be refilled with chemistry's help. - Mop: Large, infinite, limited. Needs a water bucket. - Damp Rag: Small, infinite, limited. Need to clean it after a few goes. 🆑 Melbert balance: Damp Rags can now get dirty when using them to clean blood, passing blood DNA along. add: Gauze now gets dirty when apply it to actively bleeding wounds. Doesn't spread disease or anything, just passes blood DNA. It can be cleaned in a sink. del: Removed cloth on sink / gauze on sink interaction to make rags. Just use the crafting menu /🆑
161 lines
5.7 KiB
Plaintext
161 lines
5.7 KiB
Plaintext
/obj/effect/decal/cleanable
|
|
gender = PLURAL
|
|
layer = CLEANABLE_FLOOR_OBJECT_LAYER
|
|
var/list/random_icon_states = null
|
|
///I'm sorry but cleanable/blood code is ass, and so is blood_DNA
|
|
var/blood_state = ""
|
|
///0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints
|
|
var/bloodiness = 0
|
|
///When two of these are on a same tile or do we need to merge them into just one?
|
|
var/mergeable_decal = TRUE
|
|
var/beauty = 0
|
|
///The type of cleaning required to clean the decal. See __DEFINES/cleaning.dm for the options
|
|
var/clean_type = CLEAN_TYPE_LIGHT_DECAL
|
|
///The reagent this decal holds. Leave blank for none.
|
|
var/datum/reagent/decal_reagent
|
|
///The amount of reagent this decal holds, if decal_reagent is defined
|
|
var/reagent_amount = 0
|
|
/// If TRUE, gains TRAIT_MOPABLE on init - thus this cleanable will cleaned if its turf is cleaned
|
|
/// Set to FALSE for things that hang high on the walls or things which generally shouldn't be mopped up
|
|
var/is_mopped = TRUE
|
|
|
|
/// Creates a cleanable decal on a turf
|
|
/// Use this if your decal is one of one, and thus we should not spawn it if it's there already
|
|
/// Returns either the existing cleanable, the one we created, or null if we can't spawn on that turf
|
|
/turf/proc/spawn_unique_cleanable(obj/effect/decal/cleanable/cleanable_type)
|
|
var/turf/checkturf = src
|
|
while (isgroundlessturf(checkturf) && checkturf.zPassOut(DOWN))
|
|
var/turf/below = GET_TURF_BELOW(checkturf)
|
|
if (!below || !below.zPassIn(DOWN))
|
|
break
|
|
checkturf = below
|
|
|
|
// There is no need to spam unique cleanables, they don't stack and it just chews cpu
|
|
var/obj/effect/decal/cleanable/existing = locate(cleanable_type) in checkturf
|
|
if(existing)
|
|
return existing
|
|
return new cleanable_type(checkturf)
|
|
|
|
/obj/effect/decal/cleanable/Initialize(mapload, list/datum/disease/diseases)
|
|
. = ..()
|
|
if (random_icon_states && (icon_state == initial(icon_state)) && length(random_icon_states) > 0)
|
|
icon_state = pick(random_icon_states)
|
|
create_reagents(300)
|
|
if(decal_reagent)
|
|
reagents.add_reagent(decal_reagent, reagent_amount)
|
|
if(loc && isturf(loc))
|
|
for(var/obj/effect/decal/cleanable/C in loc)
|
|
if(C != src && C.type == type && !QDELETED(C))
|
|
if (replace_decal(C))
|
|
handle_merge_decal(C)
|
|
return INITIALIZE_HINT_QDEL
|
|
|
|
if(is_mopped)
|
|
ADD_TRAIT(src, TRAIT_MOPABLE, INNATE_TRAIT)
|
|
|
|
if(LAZYLEN(diseases))
|
|
var/list/datum/disease/diseases_to_add = list()
|
|
for(var/datum/disease/D in diseases)
|
|
if(D.spread_flags & DISEASE_SPREAD_CONTACT_FLUIDS)
|
|
diseases_to_add += D
|
|
if(LAZYLEN(diseases_to_add))
|
|
AddComponent(/datum/component/infective, diseases_to_add)
|
|
|
|
AddElement(/datum/element/beauty, beauty)
|
|
|
|
var/turf/T = get_turf(src)
|
|
if(T && is_station_level(T.z))
|
|
SSblackbox.record_feedback("tally", "station_mess_created", 1, name)
|
|
var/static/list/loc_connections = list(
|
|
COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
|
|
)
|
|
AddElement(/datum/element/connect_loc, loc_connections)
|
|
|
|
/obj/effect/decal/cleanable/Destroy()
|
|
var/turf/T = get_turf(src)
|
|
if(T && is_station_level(T.z))
|
|
SSblackbox.record_feedback("tally", "station_mess_destroyed", 1, name)
|
|
return ..()
|
|
|
|
/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal
|
|
if(mergeable_decal)
|
|
return TRUE
|
|
|
|
/obj/effect/decal/cleanable/attackby(obj/item/W, mob/user, list/modifiers)
|
|
if((istype(W, /obj/item/reagent_containers/cup) && !istype(W, /obj/item/rag)) || istype(W, /obj/item/reagent_containers/cup/glass))
|
|
if(src.reagents && W.reagents)
|
|
. = 1 //so the containers don't splash their content on the src while scooping.
|
|
if(!src.reagents.total_volume)
|
|
to_chat(user, span_notice("[src] isn't thick enough to scoop up!"))
|
|
return
|
|
if(W.reagents.total_volume >= W.reagents.maximum_volume)
|
|
to_chat(user, span_notice("[W] is full!"))
|
|
return
|
|
to_chat(user, span_notice("You scoop up [src] into [W]!"))
|
|
reagents.trans_to(W, reagents.total_volume, transferred_by = user)
|
|
if(!reagents.total_volume) //scooped up all of it
|
|
qdel(src)
|
|
return
|
|
if(W.get_temperature()) //todo: make heating a reagent holder proc
|
|
if(istype(W, /obj/item/cigarette))
|
|
return
|
|
else
|
|
var/hotness = W.get_temperature()
|
|
reagents.expose_temperature(hotness)
|
|
to_chat(user, span_notice("You heat [name] with [W]!"))
|
|
else
|
|
return ..()
|
|
|
|
/obj/effect/decal/cleanable/fire_act(exposed_temperature, exposed_volume)
|
|
if(reagents)
|
|
reagents.expose_temperature(exposed_temperature)
|
|
..()
|
|
|
|
|
|
//Add "bloodiness" of this blood's type, to the human's shoes
|
|
//This is on /cleanable because fuck this ancient mess
|
|
/obj/effect/decal/cleanable/proc/on_entered(datum/source, atom/movable/AM)
|
|
SIGNAL_HANDLER
|
|
if(iscarbon(AM) && blood_state && bloodiness >= 40)
|
|
SEND_SIGNAL(AM, COMSIG_STEP_ON_BLOOD, src)
|
|
update_appearance()
|
|
|
|
/obj/effect/decal/cleanable/wash(clean_types)
|
|
. = ..()
|
|
if (. || (clean_types & clean_type))
|
|
qdel(src)
|
|
return TRUE
|
|
return .
|
|
|
|
/**
|
|
* Checks if this decal is a valid decal that can be blood crawled in.
|
|
*/
|
|
/obj/effect/decal/cleanable/proc/can_bloodcrawl_in()
|
|
if((blood_state != BLOOD_STATE_OIL) && (blood_state != BLOOD_STATE_NOT_BLOODY))
|
|
return bloodiness
|
|
|
|
return FALSE
|
|
|
|
/**
|
|
* Gets the color associated with the any blood present on this decal. If there is no blood, returns null.
|
|
*/
|
|
/obj/effect/decal/cleanable/proc/get_blood_color()
|
|
switch(blood_state)
|
|
if(BLOOD_STATE_HUMAN)
|
|
return rgb(149, 10, 10)
|
|
if(BLOOD_STATE_XENO)
|
|
return rgb(43, 186, 0)
|
|
if(BLOOD_STATE_OIL)
|
|
return rgb(22, 22, 22)
|
|
|
|
return null
|
|
|
|
/obj/effect/decal/cleanable/blood/get_blood_color()
|
|
return color || ..()
|
|
|
|
/obj/effect/decal/cleanable/proc/handle_merge_decal(obj/effect/decal/cleanable/merger)
|
|
if(!merger)
|
|
return
|
|
if(merger.reagents && reagents)
|
|
reagents.trans_to(merger, reagents.total_volume)
|