Files
Bubberstation/code/datums/components/grillable.dm
Jacquerel 04a67230b4 Grillable foods grill in hot air (#88914)
## About The Pull Request

This PR makes is so that if the air is hot enough to trigger a fire door
to close, grillable foods left out in the open will grill themselves.
I picked the minimum grilling temperature essentially at random because
I don't know what heat units are or should be, but the define
`FIRE_MINIMUM_TEMPERATURE_TO_EXIST` sounded about right.

IMPORTANT NOTE: **All foods are grillable by default** and become
"burned mess" after about 30 seconds.
If this seems like too much of a grief vector (a significant fire in the
kitchen may cause all food to grill itself into oblivion) I can make
this optional rather than a default-enabled thing on all food. IDK
whether or not this matters, because all food is also flammable.

Food will only grill based on air temperature if it is set out on an
open tile (including while on a table), not while in your hands or
backpack or pockets or a closet or inside an oven or (oddly enough)
while on a grill.

## Why It's Good For The Game

it increases my emulsion if eggs can fry on a hot sidewalk

## Changelog

🆑
add: Eggs (and all other edible food) left in a hot place will fry.
/🆑
2025-01-18 14:25:39 +01:00

215 lines
8.1 KiB
Plaintext

#define IDEAL_GRILLING_TEMPERATURE 200 + T0C
/datum/component/grillable
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS // So you can change grill results with various cookstuffs
///Result atom type of grilling this object
var/atom/cook_result
///Amount of time required to cook the food
var/required_cook_time = 2 MINUTES
///Is this a positive grill result?
var/positive_result = TRUE
///Time spent cooking so far
var/current_cook_time = 0
///Do we use the large steam sprite?
var/use_large_steam_sprite = FALSE
/// REF() to the mind which placed us on the griddle
var/who_placed_us
/// Reagents that should be added to the result
var/list/added_reagents
/// Open turf we were last placed on, to check temperature
var/turf/open/listening_turf
/// Are we grilling right now?
var/is_grilling = FALSE
/// What's our current air temperature?
var/current_temperature = 0
/datum/component/grillable/Initialize(cook_result, required_cook_time, positive_result, use_large_steam_sprite, list/added_reagents)
. = ..()
if(!isitem(parent)) //Only items support grilling at the moment
return COMPONENT_INCOMPATIBLE
src.cook_result = cook_result
src.required_cook_time = required_cook_time
src.positive_result = positive_result
src.use_large_steam_sprite = use_large_steam_sprite
src.added_reagents = added_reagents
/datum/component/grillable/RegisterWithParent()
RegisterSignal(parent, COMSIG_ITEM_GRILL_PLACED, PROC_REF(on_grill_placed))
RegisterSignal(parent, COMSIG_ITEM_GRILL_TURNED_ON, PROC_REF(on_grill_turned_on))
RegisterSignal(parent, COMSIG_ITEM_GRILL_TURNED_OFF, PROC_REF(on_grill_turned_off))
RegisterSignal(parent, COMSIG_ITEM_GRILL_PROCESS, PROC_REF(on_grill))
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_location_changed))
on_location_changed(parent)
/datum/component/grillable/UnregisterFromParent()
if (listening_turf)
UnregisterSignal(listening_turf, COMSIG_TURF_EXPOSE)
UnregisterSignal(parent, list(
COMSIG_ATOM_EXAMINE,
COMSIG_ITEM_GRILL_TURNED_ON,
COMSIG_ITEM_GRILL_TURNED_OFF,
COMSIG_ITEM_GRILL_PROCESS,
COMSIG_ITEM_GRILL_PLACED,
COMSIG_MOVABLE_MOVED
))
// Inherit the new values passed to the component
/datum/component/grillable/InheritComponent(datum/component/grillable/new_comp, original, cook_result, required_cook_time, positive_result, use_large_steam_sprite)
if(!original)
return
if(cook_result)
src.cook_result = cook_result
if(required_cook_time)
src.required_cook_time = required_cook_time
if(positive_result)
src.positive_result = positive_result
if(use_large_steam_sprite)
src.use_large_steam_sprite = use_large_steam_sprite
/datum/component/grillable/Destroy(force)
. = ..()
STOP_PROCESSING(SSmachines, src)
listening_turf = null
/// Signal proc for [COMSIG_MOVABLE_MOVED], our location has changed and we should register for temperature information
/datum/component/grillable/proc/on_location_changed(atom/source)
SIGNAL_HANDLER
if (is_grilling)
on_grill_turned_off(source)
STOP_PROCESSING(SSmachines, src)
if (listening_turf)
UnregisterSignal(listening_turf, COMSIG_TURF_EXPOSE)
if (isnull(source))
return
var/turf/open/current_turf = source.loc
if (!isopenturf(current_turf))
return
listening_turf = current_turf
RegisterSignal(current_turf, COMSIG_TURF_EXPOSE, PROC_REF(on_turf_atmos_changed))
on_turf_atmos_changed(current_turf, current_turf.air, current_turf.air?.temperature || 0)
/// Signal proc for [COMSIG_ITEM_GRILL_PLACED], item is placed on the grill.
/datum/component/grillable/proc/on_grill_placed(datum/source, mob/griller)
SIGNAL_HANDLER
if(griller && griller.mind)
who_placed_us = REF(griller.mind)
/// Signal proc for [COMSIG_ITEM_GRILL_TURNED_ON], starts the grilling process.
/datum/component/grillable/proc/on_grill_turned_on(datum/source)
RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(add_grilled_item_overlay))
is_grilling = TRUE
var/atom/atom_parent = parent
atom_parent.update_appearance()
/// Signal proc for [COMSIG_ITEM_GRILL_TURNED_OFF], stops the grilling process.
/datum/component/grillable/proc/on_grill_turned_off(datum/source)
UnregisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS)
is_grilling = FALSE
var/atom/atom_parent = parent
atom_parent.update_appearance()
///Ran every time an item is grilled by something
/datum/component/grillable/proc/on_grill(datum/source, atom/used_grill, seconds_per_tick = 1)
SIGNAL_HANDLER
. = COMPONENT_HANDLED_GRILLING
current_cook_time += seconds_per_tick * 10 //turn it into ds
if(current_cook_time >= required_cook_time)
finish_grilling(used_grill)
///Ran when an object finished grilling
/datum/component/grillable/proc/finish_grilling(atom/grill_source)
var/atom/original_object = parent
var/atom/grilled_result
if(isstack(parent)) //Check if its a sheet, for grilling multiple things in a stack
var/obj/item/stack/stack_parent = original_object
grilled_result = new cook_result(original_object.loc, stack_parent.amount)
else
grilled_result = new cook_result(original_object.loc)
if(original_object.custom_materials)
grilled_result.set_custom_materials(original_object.custom_materials)
if(IsEdible(grilled_result) && positive_result)
BLACKBOX_LOG_FOOD_MADE(grilled_result.type)
grilled_result.reagents.clear_reagents()
original_object.reagents?.trans_to(grilled_result, original_object.reagents.total_volume)
if(added_reagents) // Add any new reagents that should be added
grilled_result.reagents.add_reagent_list(added_reagents)
SEND_SIGNAL(parent, COMSIG_ITEM_GRILLED, grilled_result)
if(who_placed_us)
ADD_TRAIT(grilled_result, TRAIT_FOOD_CHEF_MADE, who_placed_us)
grill_source.visible_message("<span class='[positive_result ? "notice" : "warning"]'>[parent] turns into \a [grilled_result]!</span>")
grilled_result.pixel_x = original_object.pixel_x
grilled_result.pixel_y = original_object.pixel_y
qdel(parent)
///Ran when an object almost finishes grilling
/datum/component/grillable/proc/on_examine(atom/A, mob/user, list/examine_list)
SIGNAL_HANDLER
if(!current_cook_time) //Not grilled yet
if(positive_result)
if(initial(cook_result.name) == PLURAL)
examine_list += span_notice("[parent] can be [span_bold("grilled")] into some [initial(cook_result.name)].")
else
examine_list += span_notice("[parent] can be [span_bold("grilled")] into \a [initial(cook_result.name)].")
return
if(positive_result)
if(current_cook_time <= required_cook_time * 0.75)
examine_list += span_notice("[parent] probably needs to be cooked a bit longer!")
else if(current_cook_time <= required_cook_time)
examine_list += span_notice("[parent] seems to be almost finished cooking!")
else
examine_list += span_danger("[parent] should probably not be put on the grill.")
/datum/component/grillable/proc/add_grilled_item_overlay(datum/source, list/overlays)
SIGNAL_HANDLER
overlays += mutable_appearance('icons/effects/steam.dmi', "[use_large_steam_sprite ? "steam_triple" : "steam_single"]", ABOVE_OBJ_LAYER)
/// Signal proc for [COMSIG_TURF_EXPOSE], atmosphere might be hot enough for grilling.
/datum/component/grillable/proc/on_turf_atmos_changed(turf/open/source, datum/gas_mixture/air, exposed_temperature)
SIGNAL_HANDLER
if (!is_grilling)
if (exposed_temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
return
on_grill_turned_on(source)
START_PROCESSING(SSmachines, src)
current_temperature = exposed_temperature
else
if (exposed_temperature >= FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
current_temperature = exposed_temperature
return
on_grill_turned_off(source)
STOP_PROCESSING(SSmachines, src)
// Grill while exposed to hot air
/datum/component/grillable/process(seconds_per_tick)
var/atom/atom_parent = parent
// Grill faster as we approach 200 degrees celsius
var/check_temperature = clamp(current_temperature, FIRE_MINIMUM_TEMPERATURE_TO_EXIST, IDEAL_GRILLING_TEMPERATURE)
var/temp_scale = (check_temperature - FIRE_MINIMUM_TEMPERATURE_TO_EXIST) / (IDEAL_GRILLING_TEMPERATURE - FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
var/speed_modifier = LERP(0.5, 1, temp_scale)
on_grill(parent, atom_parent.loc, seconds_per_tick * speed_modifier)
#undef IDEAL_GRILLING_TEMPERATURE