Skip to content

Commit

Permalink
Heating up reagents in food when cooking (#33679)
Browse files Browse the repository at this point in the history
* Heating up reagents in food when cooking.

* .

* Cooktop-specific thermal transfer to cooking vessel reagents.

* .

* Heating non-reagent pan content's reagents if there are no reagents directly in the pan itself.

* Don't make stuff scalding hot when cooked in a pan.

* Allow arcane tampered cooking machines to bring food to scalding temperatures.

* .

* Avoid redundant thermal calculations.

* Update recipes_microwave.dm

* Update setup.dm

* Update setup.dm
  • Loading branch information
Hinaichigo authored Nov 23, 2022
1 parent dfe6e4b commit 0f16cd6
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 51 deletions.
9 changes: 6 additions & 3 deletions __DEFINES/setup.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1834,14 +1834,17 @@ var/list/weekend_days = list("Friday", "Saturday", "Sunday")
#define MUZZLE_SOFT 1 //Muzzle causes muffled speech.
#define MUZZLE_HARD 2 //Muzzle prevents speech.

//Microwave-or-pan selective cookability of recipes
//Cooking vessel-selective cookability of recipes
#define COOKABLE_WITH_MICROWAVE (1<<0)
#define COOKABLE_WITH_PAN (1<<1)
#define COOKABLE_WITH_MIXING (1<<2) //For things like salads and ice cream that don't require heat to cook (when mixing bowls are implemented, for now this is just used to not heat those recipes when they're made in a microwave).
#define COOKABLE_WITH_HEAT (COOKABLE_WITH_MICROWAVE | COOKABLE_WITH_PAN)
#define COOKABLE_WITH_ALL ALL

//Flags for the contents of a cooking vessel
#define COOKVESSEL_CONTAINS_REAGENTS (1<<0) //The cooking vessel contains reagents
#define COOKVESSEL_CONTAINS_CONTENTS (1<<1) //The cooking vessel contains non-reagent contents (eg. items)

//Default cooking temperature
#define COOKTEMP_DEFAULT T0C + 316 //Around 600 F
//Cooking-related temperatures
#define COOKTEMP_DEFAULT (T0C + 316) //Default cooking temperature, around 600 F
#define COOKTEMP_HUMANSAFE (BODYTEMP_HEAT_DAMAGE_LIMIT - 1) //Human-safe temperature for cooked food, 1 degree less than the threshold for burning a human.
2 changes: 1 addition & 1 deletion code/datums/recipe.dm
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
var/result //Result of a complete recipe. result = /obj/item/weapon/reagent_containers/food/snacks/donut/normal
var/time = 10 SECONDS //Length of time it takes to complete the recipe. In 10ths of a second
var/priority = 0 //To check which recipe takes priority if they share ingredients
var/cookable_with = COOKABLE_WITH_ALL //How this recipe can be cooked, eg. COOKABLE_WITH_MICROWAVE (see setup.dm).
var/cookable_with = COOKABLE_WITH_HEAT //How this recipe can be cooked, eg. COOKABLE_WITH_MICROWAVE (see setup.dm).

/*
check_reagents function
Expand Down
25 changes: 22 additions & 3 deletions code/game/machinery/kitchen/microwave.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
anchored = 1
use_power = MACHINE_POWER_USE_IDLE
idle_power_usage = 5
active_power_usage = 100
active_power_usage = 500
machine_flags = SCREWTOGGLE | CROWDESTROY | WRENCHMOVE | EJECTNOTDEL | EMAGGABLE
flags = OPENCONTAINER | NOREACT
pass_flags = PASSTABLE
Expand Down Expand Up @@ -64,7 +64,7 @@
create_reagents(100)

if (!available_recipes)
available_recipes = generate_available_recipes(flags = COOKABLE_WITH_MICROWAVE)
available_recipes = generate_available_recipes(flags = COOKABLE_WITH_MICROWAVE | COOKABLE_WITH_MIXING) //Allow things like salads to be made in a microwave while mixing bowls are unimplemented.
acceptable_reagents = new
for (var/datum/recipe/recipe in available_recipes)
for (var/item in recipe.items)
Expand Down Expand Up @@ -406,9 +406,28 @@
cooked = fail()
stop()
if(cooked)
adjust_cooked_food_reagents_temperature(cooked, recipe)
cooked.forceMove(src.loc)
return

/obj/machinery/microwave/proc/adjust_cooked_food_reagents_temperature(atom/cooked, datum/recipe/cookedrecipe)
//Put the energy used during the cooking into heating the reagents of the food.

var/cooktime = 10 SECONDS //Use a default to account for burned messes, etc.

if(cookedrecipe)
cooktime = cookedrecipe.time
//If we cooked something like ice cream or salad, abort to avoid hot ice cream.
if(cookedrecipe.cookable_with == COOKABLE_WITH_MIXING)
if(!istype(cooked, /obj/item/weapon/reagent_containers/food/snacks/badrecipe)) //Continue and heat up burned messes for valid, salad-like recipes in the case of emagged, etc.
return

var/thermal_energy_transfer = cooktime * active_power_usage * 0.9 / (1 SECONDS) //Let's assume 90% efficiency. One area for expansion could be to have this depend on upgrades.
var/max_temperature = COOKTEMP_HUMANSAFE
if(emagged || arcanetampered)
max_temperature = INFINITY //If it's been messed with, let it heat more than that.
cooked.reagents.heating(thermal_energy_transfer, max_temperature)

/obj/machinery/microwave/proc/running(var/seconds as num) // was called wzhzhzh, for some fucking reason
for (var/i=1 to seconds)
if (stat & (NOPOWER|BROKEN|FORCEDISABLE))
Expand All @@ -420,7 +439,7 @@
/obj/machinery/microwave/proc/has_extra_item()
for (var/obj/O in contents)
if ( \
!istype(O,/obj/item/weapon/reagent_containers/food) && \
!istype(O, /obj/item/weapon/reagent_containers/food) && \
!istype(O, /obj/item/weapon/grown) \
)
return 1
Expand Down
25 changes: 18 additions & 7 deletions code/game/objects/items/weapons/pan.dm
Original file line number Diff line number Diff line change
Expand Up @@ -370,20 +370,35 @@
if(!(O?.can_cook())) //if eg. the power went out on the grill, don't cook
return

var/contains_anything = contains_anything()

//If there are any reagents in the pan, heat them.
if(contains_anything & COOKVESSEL_CONTAINS_REAGENTS)
reagents.heating(O.cook_energy(), O.cook_temperature())
//Otherwise if there are non-reagent contents, heat the reagents in those contents if possible.
else
var/cook_energy = O.cook_energy()
var/cook_temperature = O.cook_temperature()
for(var/atom/content in contents)
content.reagents.heating(cook_energy / contents.len, cook_temperature)

cookingprogress += (SS_WAIT_FAST_OBJECTS * speed_multiplier)

if(cookingprogress >= (currentrecipe ? currentrecipe.time : 10 SECONDS) && !burned) //it's done when it's cooked for the cooking time, or a default of 10 seconds if there's no valid recipe. also if it's already been burned, don't keep looping burned mess -> burned mess.

var/contains_anything = contains_anything()

reset_cooking_progress() //reset the cooking progress

var/obj/cooked
if(currentrecipe)
cooked = currentrecipe.make_food(src, chef)
//If we cooked successfully, don't make the reagents in the food too hot.
if(!arcanetampered)
if(cooked.reagents.total_volume)
if(cooked.reagents.chem_temp > COOKTEMP_HUMANSAFE)
cooked.reagents.chem_temp = COOKTEMP_HUMANSAFE
visible_message("<span class='notice'>[cooked] looks done.</span>")
playsound(src, 'sound/effects/frying.ogg', 50, 1)
else if(contains_anything & COOKVESSEL_CONTAINS_CONTENTS) //Don't make a burned mess out of just reagents, even though recipes can call for only reagents (spaghetti). Just keep heating the reagents.
else if(contains_anything & COOKVESSEL_CONTAINS_CONTENTS) //Don't make a burned mess out of just reagents, even though recipes can call for only reagents (spaghetti). This allows using the pan to heat reagents.
cooked = cook_fail()

if(cooked)
Expand All @@ -395,10 +410,6 @@
//re-check the recipe. generally this will return null because we'll continue cooking the previous result, which will lead to a burned mess
currentrecipe = select_recipe(available_recipes, src)

//If there are any reagents in the pan, heat them.
if(reagents.total_volume)
reagents.heating(500, O ? O.cook_temperature() : COOKTEMP_DEFAULT) //Thermal transfer is half that of fire_act. Could be generalized based on the conditions of the cooktop. For example, like how bunsen burners work.

//Hotspot expose
var/turf/T = get_turf(src)
T?.hotspot_expose(O ? O.cook_temperature() : COOKTEMP_DEFAULT, 500, 1, surfaces = 0) //Everything but the first arg is taken from igniter.
Expand Down
3 changes: 3 additions & 0 deletions code/game/objects/objs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ var/global/list/reagents_to_log = list(FUEL, PLASMA, PACID, SACID, AMUTATIONTOXI
/obj/proc/cook_temperature() //Returns the temperature the object cooks at.
return COOKTEMP_DEFAULT

/obj/proc/cook_energy() //Returns the energy transferred to the reagents in the cooking vessel per process() tick of the cooking vessel. Cooking vessels use the fast objects subsystem.
return 500 //Half that of fire_act().

/obj/proc/generate_available_recipes(flags = COOKABLE_WITH_ALL)
var/list/recipes = list()
for(var/type in (typesof(/datum/recipe) - /datum/recipe))
Expand Down
17 changes: 13 additions & 4 deletions code/modules/food/cooking_machines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ var/global/ingredientLimit = 10
else
icon_state = initial(icon_state)

/////////////////////Cooking stuff/////////////////////
/////////////////////Cooking vessel stuff/////////////////////
/obj/machinery/cooking/can_cook() //Whether or not we are in a valid state to cook the contents of a cooking vessel.
. = ..()
if(stat & (FORCEDISABLE | NOPOWER | BROKEN))
Expand All @@ -151,6 +151,9 @@ var/global/ingredientLimit = 10
overlays.len = 0
..()

/obj/machinery/cooking/cook_energy()
return active_power_usage * SS_WAIT_FAST_OBJECTS * 0.9 / (1 SECONDS) //Assumes 90% efficiency. Could be expanded to depend on upgrades.

// Interactions ////////////////////////////////////////////////

/obj/machinery/cooking/examine(mob/user)
Expand Down Expand Up @@ -512,6 +515,8 @@ var/global/ingredientLimit = 10
if(istype(ingredient,/obj/item/weapon/reagent_containers/food/snacks))
if(cooks_in_reagents)
transfer_reagents_to_food(ingredient)
if(!arcanetampered && (ingredient.reagents.chem_temp > COOKTEMP_HUMANSAFE)) //Since gradual cooling isn't implemented, make sure the food isn't scalding hot.
ingredient.reagents.chem_temp = COOKTEMP_HUMANSAFE
ingredient.name = "deep fried [ingredient.name]"
ingredient.color = "#FFAD33"
ingredient.forceMove(loc)
Expand All @@ -521,6 +526,8 @@ var/global/ingredientLimit = 10
var/obj/item/weapon/reagent_containers/food/snacks/deepfryholder/D = new(loc)
if(cooks_in_reagents)
transfer_reagents_to_food(D)
if(!arcanetampered && (D.reagents.chem_temp > COOKTEMP_HUMANSAFE)) //Same as above.
D.reagents.chem_temp = COOKTEMP_HUMANSAFE
D.name = "deep fried [ingredient.name]"
D.color = "#FFAD33"
D.icon = ingredient.icon
Expand Down Expand Up @@ -558,7 +565,6 @@ var/global/ingredientLimit = 10
takeIngredient(I, L, TRUE) //shove the item in, even if it can't be deepfried normally
empty_icon()


// confectionator ///////////////////////////////////////
// its like a deepfrier

Expand Down Expand Up @@ -715,6 +721,10 @@ var/global/ingredientLimit = 10
ingredient = null
return

/obj/machinery/cooking/grill/process()
if(ingredient)
ingredient.reagents.heating(active_power_usage * 0.9 * SS_WAIT_MACHINERY / (1 SECONDS), arcanetampered ? INFINITY : COOKTEMP_HUMANSAFE) //Assume 90% efficiency. Could be expanded to depend on upgrades.

/obj/machinery/cooking/grill/spit
name = "spit"
desc = "the prime in clown cooking technology."
Expand Down Expand Up @@ -759,7 +769,6 @@ var/global/ingredientLimit = 10
if(!campfirefound)
. = "There's no campfire to cook on!"


//=====Actual fucking sensible cooking machines that don't magic bullshit out of thin air

/obj/machinery/oven
Expand Down Expand Up @@ -858,7 +867,7 @@ var/global/ingredientLimit = 10
if(use_power == MACHINE_POWER_USE_NONE)
toggle()
if(within)
within.attempt_heating(src)
within.reagents.heating(active_power_usage * 0.9 * SS_WAIT_MACHINERY / (1 SECONDS), arcanetampered ? INFINITY : COOKTEMP_HUMANSAFE) //Assume 90% efficiency. One area of expansion could be to make this depend on upgrades.

/obj/machinery/cooking/foodpress
name = "food press"
Expand Down
Loading

0 comments on commit 0f16cd6

Please sign in to comment.