Files
nevimer b348b617a3 Merge branch 'master' of https://github.com/tgstation/tgstation into pupstream-2025-09-07
# Conflicts:
#	README.md
#	code/__DEFINES/admin.dm
#	code/__DEFINES/melee.dm
#	code/_globalvars/traits/_traits.dm
#	code/controllers/subsystem/economy.dm
#	code/datums/components/crafting/crafting.dm
#	code/datums/elements/crusher_loot.dm
#	code/modules/antagonists/pirate/pirate_shuttle_equipment.dm
#	code/modules/clothing/suits/_suits.dm
#	code/modules/escape_menu/leave_body.dm
#	code/modules/jobs/job_types/_job.dm
#	code/modules/mining/equipment/mineral_scanner.dm
#	code/modules/mob/living/living.dm
#	code/modules/plumbing/plumbers/pill_press.dm
#	tgui/packages/tgui/interfaces/Vending.tsx
2025-09-07 00:37:52 -04:00

144 lines
5.6 KiB
Plaintext

//"Don't leave food on the floor, that's how we get ants"
#define DECOMPOSITION_TIME (20 MINUTES) // SKYRAT EDIT CHANGE - ORIGINAL: #define DECOMPOSITION_TIME (10 MINUTES)
#define DECOMPOSITION_TIME_RAW (15 MINUTES) // SKYRAT EDIT CHANGE - ORIGINAL: #define DECOMPOSITION_TIME_RAW (5 MINUTES)
#define DECOMPOSITION_TIME_GROSS (10 MINUTES) // SKYRAT EDIT CHANGE, - ORIGINAL: #define DECOMPOSITION_TIME_GROSS (7 MINUTES)
///Makes things decompose when exposed to germs. Requires /datum/component/germ_sensitive to detect exposure.
/datum/component/decomposition
dupe_mode = COMPONENT_DUPE_UNIQUE
/// Makes sure maploaded food only starts decomposing if a player's EVER picked it up before
var/handled = TRUE
/// Used to stop food in someone's hand & in storage slots from decomposing.
var/protected = FALSE
/// The total time that this takes to decompose
var/original_time = DECOMPOSITION_TIME
/// Used so the timer won't reset.
var/time_remaining = DECOMPOSITION_TIME
/// Used to create stink lines when the food is close to going bad
var/stink_timerid
/// Used to stop decomposition & check for the examine proc
var/decomp_timerid
/// Used to give raw/gross food lower timers
var/decomp_flags
/// Use for determining what kind of item the food decomposes into.
var/decomp_result
/// Does our food attract ants?
var/produce_ants = FALSE
/// Stink particle type, if we are supposed to create stink particles
var/stink_particles
/datum/component/decomposition/Initialize(mapload, decomp_req_handle, decomp_flags = NONE, decomp_result, ant_attracting = FALSE, custom_time = 0, stink_particles = /particles/stink)
if(!ismovable(parent) || !HAS_TRAIT(parent, TRAIT_GERM_SENSITIVE))
return COMPONENT_INCOMPATIBLE
src.decomp_flags = decomp_flags
src.decomp_result = decomp_result
if(mapload || decomp_req_handle)
handled = FALSE
src.produce_ants = ant_attracting
if(custom_time) // We have a custom decomposition time, set it to that
original_time = custom_time
else if(decomp_flags & RAW) // Raw food overrides gross
original_time = DECOMPOSITION_TIME_RAW
else if(decomp_flags & GROSS)
original_time = DECOMPOSITION_TIME_GROSS
time_remaining = original_time
src.stink_particles = stink_particles
/datum/component/decomposition/Destroy()
remove_timer()
if (stink_particles)
var/atom/movable/movable_parent = parent
movable_parent.remove_shared_particles("[stink_particles]_[isitem(parent)]")
return ..()
/datum/component/decomposition/RegisterWithParent()
RegisterSignal(parent, COMSIG_ATOM_GERM_EXPOSED, PROC_REF(start_timer))
RegisterSignal(parent, COMSIG_ATOM_GERM_UNEXPOSED, PROC_REF(remove_timer))
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(examine))
/datum/component/decomposition/UnregisterFromParent()
UnregisterSignal(parent, list(
COMSIG_ATOM_GERM_EXPOSED,
COMSIG_ATOM_GERM_UNEXPOSED,
COMSIG_ATOM_EXAMINE
))
/datum/component/decomposition/proc/start_timer()
SIGNAL_HANDLER
if(!handled) // If maploaded, has someone touched this previously?
handled = TRUE // First germ exposure is ignored
return
// If all other checks fail, then begin decomposition.
decomp_timerid = addtimer(CALLBACK(src, PROC_REF(decompose)), time_remaining, TIMER_STOPPABLE | TIMER_UNIQUE)
// Also start the stinking timer, if have stink particles
if(!stink_particles)
return
var/stink_time = max(0, time_remaining - (original_time * 0.5))
stink_timerid = addtimer(CALLBACK(src, PROC_REF(stink_up)), stink_time, TIMER_STOPPABLE | TIMER_UNIQUE)
/// Returns the time remaining in decomp, either from our potential timer or our own value, whichever is more useful
/datum/component/decomposition/proc/get_time()
if(!decomp_timerid)
return time_remaining
return timeleft(decomp_timerid)
/datum/component/decomposition/proc/remove_timer()
if(!decomp_timerid)
return
time_remaining = timeleft(decomp_timerid)
deltimer(decomp_timerid)
decomp_timerid = null
if(!stink_timerid)
return
deltimer(stink_timerid)
stink_timerid = null
/datum/component/decomposition/proc/stink_up()
stink_timerid = null
// Shouldn't happen, but to be sure
if(!stink_particles)
return
// we don't want stink lines on mobs (even though it'd be quite funny)
var/atom/movable/movable_parent = parent
movable_parent.add_shared_particles(stink_particles, "[stink_particles]_[isitem(parent)]", isitem(parent) ? NONE : PARTICLE_ATTACH_MOB)
/datum/component/decomposition/proc/decompose()
decomp_timerid = null
var/obj/decomp = parent //Lets us spawn things at decomp
if(produce_ants)
new /obj/effect/decal/cleanable/ants(decomp.loc)
if(decomp_result)
var/atom/movable/result = new decomp_result(decomp.loc)
//make space and tranfer reagents if it has any, also let any bad result handle removing or converting the transferred reagents on its own terms
if(result.reagents && decomp.reagents)
result.reagents.clear_reagents()
decomp.reagents.trans_to(result, decomp.reagents.total_volume)
SEND_SIGNAL(result, COMSIG_OBJ_DECOMPOSITION_RESULT, decomp)
decomp.visible_message(span_warning("[decomp] gets overtaken by mold[produce_ants ? " and ants":""]! Gross!"))
qdel(decomp)
return
/datum/component/decomposition/proc/examine(datum/source, mob/user, list/examine_list)
SIGNAL_HANDLER
var/time_d = get_time()
switch(time_d / original_time)
if(0.5 to 0.75) // 25% rotten
examine_list += span_notice("[parent] looks kinda stale.")
if(0.25 to 0.5) // 50% rotten
examine_list += span_notice("[parent] is starting to look pretty gross.")
if(0 to 0.25) // 75% rotten
examine_list += span_danger("[parent] barely looks edible.")
#undef DECOMPOSITION_TIME
#undef DECOMPOSITION_TIME_GROSS
#undef DECOMPOSITION_TIME_RAW