Files
Bloop a9925b2d39 Dev QoL improvements for the materials unit test (#94338)
## About The Pull Request

Just improves the new material unit test, making it more copy-paste
friendly when dealing with large amounts of things to change.

It now also calculates the appropriate sheet material value for you too
so you quite literally just have to copy paste the line and you're done,
no more having to do math yourself.

<img width="2104" height="155" alt="image"
src="https://github.com/user-attachments/assets/b605e423-0418-46b7-b40c-c65fac920af9"
/>


## Why It's Good For The Game

Developer qol.

## Changelog

Nothing player-facing

---------

Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
2025-12-09 21:48:31 +01:00

231 lines
9.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
var/obj/item/item_parent = parent
if(!PERFORM_ALL_TESTS(focus_only/check_materials_when_processed) || !positive_result || !item_parent.custom_materials || isstack(parent))
return
var/atom/result = new cook_result
if(!item_parent.compare_materials(result))
var/warning = "custom_materials of [result.type] when grilled compared to just spawned don't match"
var/what_it_should_be = item_parent.transcribe_materials_list()
stack_trace("[warning]. should be: custom_materials = [what_it_should_be].")
qdel(result)
/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(istype(original_object, /obj/item/food) && istype(grilled_result, /obj/item/food))
var/obj/item/food/original_food = original_object
var/obj/item/food/grilled_food = grilled_result
LAZYADD(grilled_food.intrinsic_food_materials, original_food.intrinsic_food_materials)
grilled_result.set_custom_materials(original_object.custom_materials)
if(IS_EDIBLE(grilled_result) && positive_result)
BLACKBOX_LOG_FOOD_MADE(grilled_result.type)
//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(grilled_result.reagents && original_object.reagents)
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)
SEND_SIGNAL(grilled_result, COMSIG_ITEM_GRILLED_RESULT, parent)
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