#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.get_materials_english_list() stack_trace("[warning]. custom_materials should be [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("[parent] turns into \a [grilled_result]!") 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