Files
Bubberstation/code/datums/components/food/decomposition.dm
Ghom 3ea1eb101e [NO GBP] Fix to burned mess (#92684)
## About The Pull Request
#92394 did more harm than good.

First, only the microwavable element transferred reagents even if the
result was a burned mess (in general, a non-positive one), while
grillable and bakeable comps didn't... but that's because I've
overlooked a few checks that skipped the "transfer reagents to the
result" step, which the microwavable element also has, though it stopped
working as intended after I messed with it.
However, I think it's stupid for bad recipes to have a static amount of
"bad food" reagent in them, and overcooking a whole cake shouldn't yield
the same reagents as a bag of chips burned to a crisp, so I scrapped
those damn bad_result checks, and finally let the burned mess item
itself handle converting the consumable reagents into "bad food".

Second, examining most food items no longer tells you that you can make
a burned mess if you microwave it.

## Why It's Good For The Game
This fixes the above issues.

## Changelog

🆑
fix: Examining most food items no longer tells you that you can make
burned mess by microwaving them.
fix: Burned mess now has "bad food" in it more or less proportional to
the nutrients of the item you just overcooked. This also applies to
decomposition now.
/🆑
2025-09-03 04:39:43 -07:00

144 lines
5.3 KiB
Plaintext

//"Don't leave food on the floor, that's how we get ants"
#define DECOMPOSITION_TIME (10 MINUTES)
#define DECOMPOSITION_TIME_RAW (5 MINUTES)
#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