From 6f15bf2e1454a146ad028ed0c47e84446d1a1013 Mon Sep 17 00:00:00 2001 From: NanakoAC Date: Mon, 20 Mar 2017 13:32:39 +0000 Subject: [PATCH] Emergency Cooking Fixes (#1944) This PR fixes a number of isssues with cooking that were overlooked during testing. The cause of the infinite loop: I neglected to add a buffer to hold cooked items to the microwave when i did likewise for other appliances, this is necessary for bulk cooking as it ensures that things which were just cooked, aren't considered as potential ingredients. The lack of this buffer caused donk pockets to iterate forever, because the result (a cooked donk pocket) is a valid ingredient to create a cooked donk pocket. so it made the same recipe millions of times over. This is now fixed. Runtime errors. A few items would throw runtime errors because they override the make_food function which i significantly altered, and return data in the wrong format. This is now fixed. Affected items were: Donk pockets, valid salad, fortune cookies, amanita jelly. Uncookable items. A few recipes were impossible to create in appliances due to my neglecting support for adding non-snack items to cooking containers. This mostly affects diona roast and fortune cookies.. For now i've gone with a simple whitelist approach, allowing paper and holders to be added. --- .../kitchen/cooking_machines/_appliance.dm | 7 ++-- .../kitchen/cooking_machines/_cooker.dm | 2 +- .../kitchen/cooking_machines/container.dm | 20 +++++++---- .../kitchen/cooking_machines/oven.dm | 2 +- code/game/machinery/kitchen/microwave.dm | 18 +++++++--- code/modules/food/recipes_microwave.dm | 26 +++++++------- code/modules/food/recipes_oven.dm | 35 +++++++++++++++---- .../reagent_containers/food/snacks.dm | 14 +++++--- 8 files changed, 84 insertions(+), 40 deletions(-) diff --git a/code/game/machinery/kitchen/cooking_machines/_appliance.dm b/code/game/machinery/kitchen/cooking_machines/_appliance.dm index fab66c20872..29d727f1d19 100644 --- a/code/game/machinery/kitchen/cooking_machines/_appliance.dm +++ b/code/game/machinery/kitchen/cooking_machines/_appliance.dm @@ -389,14 +389,15 @@ CI.result_type = 4//Recipe type, a specific recipe will transform the ingredients into a new food var/list/results = recipe.make_food(C) - var/atom/temp = new /atom //To prevent infinite loops, all results will be moved into a temporary location so they're not considered as inputs for other recipes + var/obj/temp = new /obj(src) //To prevent infinite loops, all results will be moved into a temporary location so they're not considered as inputs for other recipes for (var/atom/movable/AM in results) AM.loc = temp //making multiple copies of a recipe from one container. For example, tons of fries while (select_recipe(available_recipes,C) == recipe) - var/list/TR = recipe.make_food(C) + var/list/TR = list() + TR.Add(recipe.make_food(C)) for (var/atom/movable/AM in TR) //Move results to buffer AM.loc = temp results.Add(TR) @@ -636,7 +637,7 @@ //var/obj/object var/max_cookwork var/cookwork - var/overcook_mult = 2 + var/overcook_mult = 3 var/result_type = 0 var/obj/item/weapon/reagent_containers/cooking_container/container = null var/combine_target = null diff --git a/code/game/machinery/kitchen/cooking_machines/_cooker.dm b/code/game/machinery/kitchen/cooking_machines/_cooker.dm index d8bfd43dabe..84882baaa4b 100644 --- a/code/game/machinery/kitchen/cooking_machines/_cooker.dm +++ b/code/game/machinery/kitchen/cooking_machines/_cooker.dm @@ -16,7 +16,7 @@ if (.)//no need to duplicate adjacency check if (!stat) if (temperature < min_temp) - user << span("warning", "It is heating up.") + user << span("warning", "The [src] is still heating up and is too cold to cook anything yet.") else user << span("notice", "It is running at [round(get_efficiency(), 0.1)]% efficiency!") user << "Temperature: [round(temperature - T0C, 0.1)]C / [round(optimal_temp - T0C, 0.1)]C" diff --git a/code/game/machinery/kitchen/cooking_machines/container.dm b/code/game/machinery/kitchen/cooking_machines/container.dm index f9be08952ae..f1decf8c811 100644 --- a/code/game/machinery/kitchen/cooking_machines/container.dm +++ b/code/game/machinery/kitchen/cooking_machines/container.dm @@ -8,6 +8,10 @@ var/max_space = 20//Maximum sum of w-classes of foods in this container at once var/max_reagents = 80//Maximum units of reagents + var/list/insertable = list(/obj/item/weapon/reagent_containers/food/snacks, + /obj/item/weapon/holder, + /obj/item/weapon/paper) + /obj/item/weapon/reagent_containers/cooking_container/New() ..() create_reagents(max_reagents) @@ -26,15 +30,17 @@ /obj/item/weapon/reagent_containers/cooking_container/attackby(var/obj/item/I as obj, var/mob/user as mob) - if (istype(I, /obj/item/weapon/reagent_containers/food/snacks)) - if (!can_fit(I)) - user << span("warning","There's no more space in the [src] for that!") - return 0 + for (var/possible_type in insertable) + if (istype(I, possible_type)) + if (!can_fit(I)) + user << span("warning","There's no more space in the [src] for that!") + return 0 - if(!user.unEquip(I)) + if(!user.unEquip(I)) + return + I.forceMove(src) + user << span("notice", "You put the [I] into the [src]") return - I.forceMove(src) - user << span("notice", "You put the [I] into the [src]") /obj/item/weapon/reagent_containers/cooking_container/verb/empty() set src in view() diff --git a/code/game/machinery/kitchen/cooking_machines/oven.dm b/code/game/machinery/kitchen/cooking_machines/oven.dm index 48e3364c7ee..c741535df3b 100644 --- a/code/game/machinery/kitchen/cooking_machines/oven.dm +++ b/code/game/machinery/kitchen/cooking_machines/oven.dm @@ -67,7 +67,7 @@ loss = (active_power_usage / resistance)*0.5 else open = 1 - loss = (active_power_usage / resistance)*10 + loss = (active_power_usage / resistance)*6 //When the oven door is opened, heat is lost MUCH faster playsound(src, 'sound/machines/hatch_open.ogg', 20, 1) diff --git a/code/game/machinery/kitchen/microwave.dm b/code/game/machinery/kitchen/microwave.dm index 05a1f0f3bba..0396b62c64a 100644 --- a/code/game/machinery/kitchen/microwave.dm +++ b/code/game/machinery/kitchen/microwave.dm @@ -16,7 +16,7 @@ var/global/list/datum/recipe/available_recipes // List of the recipes you can use var/global/list/acceptable_items // List of the items you can put in var/global/list/acceptable_reagents // List of the reagents you can put in - var/global/max_n_of_items = 0 + var/global/max_n_of_items = 20 var/appliancetype = MICROWAVE // see code/modules/food/recipes_microwave.dm for recipes @@ -44,8 +44,6 @@ acceptable_items |= item for (var/reagent in recipe.reagents) acceptable_reagents |= reagent - if (recipe.items) - max_n_of_items = max(max_n_of_items,recipe.items.len) // This will do until I can think of a fun recipe to use dionaea in - // will also allow anything using the holder item to be microwaved into // impure carbon. ~Z @@ -295,13 +293,25 @@ var/result = recipe.result var/valid = 1 var/list/cooked_items = list() + var/obj/temp = new /obj(src) //To prevent infinite loops, all results will be moved into a temporary location so they're not considered as inputs for other recipes while(valid) - cooked_items += recipe.make_food(src) + var/list/things = list() + things.Add(recipe.make_food(src)) + cooked_items += things + //Move cooked things to the buffer so they're not considered as ingredients + for (var/atom/movable/AM in things) + AM.loc = temp + valid = 0 recipe = select_recipe(available_recipes,src) if (recipe && recipe.result == result) + sleep(2) valid = 1 + for (var/r in cooked_items) + var/atom/movable/R = r + R.loc = src //Move everything from the buffer back to the container + //Any leftover reagents are divided amongst the foods var/total = reagents.total_volume for (var/obj/item/weapon/reagent_containers/food/snacks/S in cooked_items) diff --git a/code/modules/food/recipes_microwave.dm b/code/modules/food/recipes_microwave.dm index 6b4f613f47d..3e0bc2582a0 100644 --- a/code/modules/food/recipes_microwave.dm +++ b/code/modules/food/recipes_microwave.dm @@ -146,9 +146,10 @@ I said no! proc/warm_up(var/obj/item/weapon/reagent_containers/food/snacks/donkpocket/being_cooked) being_cooked.heat() make_food(var/obj/container as obj) - var/obj/item/weapon/reagent_containers/food/snacks/donkpocket/being_cooked = ..(container) - warm_up(being_cooked) - return being_cooked + . = ..(container) + for (var/obj/item/weapon/reagent_containers/food/snacks/donkpocket/D in .) + if (!D.warm) + warm_up(D) /datum/recipe/donkpocket/warm reagents = list() //This is necessary since this is a child object of the above recipe and we don't want donk pockets to need flour @@ -156,11 +157,6 @@ I said no! /obj/item/weapon/reagent_containers/food/snacks/donkpocket ) result = /obj/item/weapon/reagent_containers/food/snacks/donkpocket //SPECIAL - make_food(var/obj/container as obj) - var/obj/item/weapon/reagent_containers/food/snacks/donkpocket/being_cooked = locate() in container - if(being_cooked && !being_cooked.warm) - warm_up(being_cooked) - return being_cooked @@ -300,9 +296,10 @@ I said no! reagents = list("water" = 5, "vodka" = 5, "amatoxin" = 5) result = /obj/item/weapon/reagent_containers/food/snacks/amanitajelly make_food(var/obj/container as obj) - var/obj/item/weapon/reagent_containers/food/snacks/amanitajelly/being_cooked = ..(container) - being_cooked.reagents.del_reagent("amatoxin") - return being_cooked + + . = ..(container) + for (var/obj/item/weapon/reagent_containers/food/snacks/amanitajelly/being_cooked in .) + being_cooked.reagents.del_reagent("amatoxin") /datum/recipe/meatballsoup fruit = list("carrot" = 1, "potato" = 1) @@ -653,9 +650,10 @@ I said no! items = list(/obj/item/weapon/reagent_containers/food/snacks/meatball) result = /obj/item/weapon/reagent_containers/food/snacks/validsalad make_food(var/obj/container as obj) - var/obj/item/weapon/reagent_containers/food/snacks/validsalad/being_cooked = ..(container) - being_cooked.reagents.del_reagent("toxin") - return being_cooked + + . = ..(container) + for (var/obj/item/weapon/reagent_containers/food/snacks/validsalad/being_cooked in .) + being_cooked.reagents.del_reagent("toxin") diff --git a/code/modules/food/recipes_oven.dm b/code/modules/food/recipes_oven.dm index 42142abb433..21bf6cf2214 100644 --- a/code/modules/food/recipes_oven.dm +++ b/code/modules/food/recipes_oven.dm @@ -226,12 +226,35 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/fortunecookie make_food(var/obj/container as obj) - var/obj/item/weapon/paper/paper = locate() in container - paper.loc = null //prevent deletion - var/obj/item/weapon/reagent_containers/food/snacks/fortunecookie/being_cooked = ..(container) - paper.loc = being_cooked - being_cooked.trash = paper //so the paper is left behind as trash without special-snowflake(TM Nodrak) code ~carn - return being_cooked + + var/obj/item/weapon/paper/paper + + //Fuck fortune cookies. This is a quick hack + //Duplicate the item searching code with a special case for paper + for (var/i in items) + var/obj/item/I = locate(i) in container + if (!paper && istype(I, /obj/item/weapon/paper)) + paper = I + continue + + if (I) + qdel(I) + + //Then store and null out the items list so it wont delete any paper + var/list/L = items.Copy() + items = null + . = ..(container) + + //Restore items list, so that making fortune cookies once doesnt break the oven + items = L + + + for (var/obj/item/weapon/reagent_containers/food/snacks/fortunecookie/being_cooked in .) + paper.loc = being_cooked + being_cooked.trash = paper //so the paper is left behind as trash without special-snowflake(TM Nodrak) code ~carn + return + + check_items(var/obj/container as obj) . = ..() if (.) diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index 46ea5d35e91..f0d45ee4204 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -979,12 +979,18 @@ proc/cooltime() if (src.warm) spawn(4200) - src.warm = 0 - for(var/reagent in heated_reagents) - src.reagents.del_reagent(reagent) - src.name = initial(name) + if(src) + src.warm = 0 + for(var/reagent in heated_reagents) + src.reagents.del_reagent(reagent) + src.name = initial(name) return +/obj/item/weapon/reagent_containers/food/snacks/donkpocket/cook() + ..() + if (!warm) + heat() + /obj/item/weapon/reagent_containers/food/snacks/brainburger name = "brainburger" desc = "A strange looking burger. It looks almost sentient."