Merge pull request #8811 from FalseIncarnate/kitchen

Mixing Bowls and Kitchen refactors
This commit is contained in:
Crazy Lemon
2018-09-26 17:32:39 -07:00
committed by GitHub
13 changed files with 335 additions and 111 deletions
@@ -5,7 +5,7 @@
icon = 'icons/obj/cooking_machines.dmi'
icon_state = "candymaker_off"
cook_verbs = list("Wonderizing", "Scrumpdiddlyumptiousification", "Miracle-coating", "Flavorifaction")
recipe_type = /datum/recipe/candy
recipe_type = RECIPE_CANDY
off_icon = "candymaker_off"
on_icon = "candymaker_on"
broken_icon = "candymaker_broke"
@@ -5,7 +5,7 @@
icon = 'icons/obj/cooking_machines.dmi'
icon_state = "grill_off"
cook_verbs = list("Grilling", "Searing", "Frying")
recipe_type = /datum/recipe/grill
recipe_type = RECIPE_GRILL
off_icon = "grill_off"
on_icon = "grill_on"
broken_icon = "grill_broke"
@@ -16,10 +16,7 @@
var/list/cook_verbs = list("Cooking")
//Recipe & Item vars
var/recipe_type //Make sure to set this on the machine definition, or else you're gonna runtime on New()
var/list/datum/recipe/available_recipes // List of the recipes you can use
var/list/acceptable_items // List of the items you can put in
var/list/acceptable_reagents // List of the reagents you can put in
var/max_n_of_items = 0
var/max_n_of_items = 25
//Icon states
var/off_icon
var/on_icon
@@ -35,23 +32,28 @@
..()
create_reagents(100)
reagents.set_reacting(FALSE)
if(!available_recipes)
available_recipes = new
acceptable_items = new
acceptable_reagents = new
for(var/type in subtypesof(recipe_type))
init_lists()
/obj/machinery/kitchen_machine/proc/init_lists()
if(!GLOB.cooking_recipes[recipe_type])
GLOB.cooking_recipes[recipe_type] = list()
GLOB.cooking_ingredients[recipe_type] = list()
GLOB.cooking_reagents[recipe_type] = list()
if(!length(GLOB.cooking_recipes[recipe_type]))
for(var/type in subtypesof(GLOB.cooking_recipe_types[recipe_type]))
var/datum/recipe/recipe = new type
if(recipe in GLOB.cooking_recipes[recipe_type])
qdel(recipe)
continue
if(recipe.result) // Ignore recipe subtypes that lack a result
available_recipes += recipe
GLOB.cooking_recipes[recipe_type] += recipe
for(var/item in recipe.items)
acceptable_items |= item
GLOB.cooking_ingredients[recipe_type] |= item
for(var/reagent in recipe.reagents)
acceptable_reagents |= reagent
if(recipe.items)
max_n_of_items = max(max_n_of_items,recipe.count_n_items())
GLOB.cooking_reagents[recipe_type] |= reagent
else
qdel(recipe)
acceptable_items |= /obj/item/reagent_containers/food/snacks/grown
GLOB.cooking_ingredients[recipe_type] |= /obj/item/reagent_containers/food/snacks/grown
/*******************
* Item Adding
@@ -80,26 +82,14 @@
if(broken > 0)
if(broken == 2 && istype(O, /obj/item/screwdriver)) // If it's broken and they're using a screwdriver
user.visible_message( \
"<span class='notice'>[user] starts to fix part of \the [src].</span>", \
"<span class='notice'>You start to fix part of \the [src].</span>" \
)
user.visible_message("<span class='notice'>[user] starts to fix part of [src].</span>", "<span class='notice'>You start to fix part of [src].</span>")
if(do_after(user, 20 * O.toolspeed, target = src))
user.visible_message( \
"<span class='notice'>[user] fixes part of \the [src].</span>", \
"<span class='notice'>You have fixed part of \the [src].</span>" \
)
user.visible_message("<span class='notice'>[user] fixes part of [src].</span>", "<span class='notice'>You have fixed part of \the [src].</span>")
broken = 1 // Fix it a bit
else if(broken == 1 && istype(O, /obj/item/wrench)) // If it's broken and they're doing the wrench
user.visible_message( \
"<span class='notice'>[user] starts to fix part of \the [src].</span>", \
"<span class='notice'>You start to fix part of \the [src].</span>" \
)
user.visible_message("<span class='notice'>[user] starts to fix part of [src].</span>", "<span class='notice'>You start to fix part of [src].</span>")
if(do_after(user, 20 * O.toolspeed, target = src))
user.visible_message( \
"<span class='notice'>[user] fixes \the [src].</span>", \
"<span class='notice'>You have fixed \the [src].</span>" \
)
user.visible_message("<span class='notice'>[user] fixes [src].</span>", "<span class='notice'>You have fixed [src].</span>")
icon_state = off_icon
broken = 0 // Fix it!
dirty = 0 // just to be sure
@@ -109,15 +99,9 @@
return 1
else if(dirty==100) // The machine is all dirty so can't be used!
if(istype(O, /obj/item/reagent_containers/spray/cleaner) || istype(O, /obj/item/soap)) // If they're trying to clean it then let them
user.visible_message( \
"<span class='notice'>[user] starts to clean \the [src].</span>", \
"<span class='notice'>You start to clean \the [src].</span>" \
)
user.visible_message("<span class='notice'>[user] starts to clean [src].</span>", "<span class='notice'>You start to clean [src].</span>")
if(do_after(user, 20 * O.toolspeed, target = src))
user.visible_message( \
"<span class='notice'>[user] has cleaned \the [src].</span>", \
"<span class='notice'>You have cleaned \the [src].</span>" \
)
user.visible_message("<span class='notice'>[user] has cleaned [src].</span>", "<span class='notice'>You have cleaned [src].</span>")
dirty = 0 // It's clean!
broken = 0 // just to be sure
icon_state = off_icon
@@ -125,33 +109,25 @@
else //Otherwise bad luck!!
to_chat(user, "<span class='alert'>It's dirty!</span>")
return 1
else if(is_type_in_list(O,acceptable_items))
else if(is_type_in_list(O, GLOB.cooking_ingredients[recipe_type]) || istype(O, /obj/item/mixing_bowl))
if(contents.len>=max_n_of_items)
to_chat(user, "<span class='alert'>This [src] is full of ingredients, you cannot put more.</span>")
return 1
if(istype(O,/obj/item/stack) && O:amount>1)
new O.type (src)
O:use(1)
user.visible_message( \
"<span class='notice'>[user] has added one of [O] to \the [src].</span>", \
"<span class='notice'>You add one of [O] to \the [src].</span>")
if(istype(O,/obj/item/stack))
var/obj/item/stack/S = O
if(S.amount > 1)
var/obj/item/stack/to_add = S.split(user, 1)
to_add.forceMove(src)
user.visible_message("<span class='notice'>[user] adds one of [S] to [src].</span>", "<span class='notice'>You add one of [S] to [src].</span>")
else
add_item(S, user)
else
if(!user.drop_item())
to_chat(user, "<span class='notice'>\The [O] is stuck to your hand, you cannot put it in \the [src]</span>")
return 0
O.forceMove(src)
user.visible_message( \
"<span class='notice'>[user] has added \the [O] to \the [src].</span>", \
"<span class='notice'>You add \the [O] to \the [src].</span>")
else if(istype(O,/obj/item/reagent_containers/glass) || \
istype(O,/obj/item/reagent_containers/food/drinks) || \
istype(O,/obj/item/reagent_containers/food/condiment) \
)
add_item(O, user)
else if(is_type_in_list(O, list(/obj/item/reagent_containers/glass, /obj/item/reagent_containers/food/drinks, /obj/item/reagent_containers/food/condiment)))
if(!O.reagents)
return 1
for(var/datum/reagent/R in O.reagents.reagent_list)
if(!(R.id in acceptable_reagents))
if(!(R.id in GLOB.cooking_reagents[recipe_type]))
to_chat(user, "<span class='alert'>Your [O] contains components unsuitable for cookery.</span>")
return 1
//G.reagents.trans_to(src,G.amount_per_transfer_from_this)
@@ -162,6 +138,14 @@
return 1
updateUsrDialog()
/obj/machinery/kitchen_machine/proc/add_item(obj/item/I, mob/user)
if(!user.drop_item())
to_chat(user, "<span class='notice'>\The [I] is stuck to your hand, you cannot put it in [src]</span>")
//return 0
else
I.forceMove(src)
user.visible_message("<span class='notice'>[user] adds [I] to [src].</span>", "<span class='notice'>You add [I] to [src].</span>")
/obj/machinery/kitchen_machine/attack_ai(mob/user)
return 0
@@ -182,11 +166,11 @@
return
var/dat = ""
if(broken > 0)
dat = {"<TT>Bzzzzttttt</TT>"}
dat = {"<code>Bzzzzttttt</code>"}
else if(operating)
dat = {"<TT>[pick(cook_verbs)] in progress!<BR>Please wait...!</TT>"}
dat = {"<code>[pick(cook_verbs)] in progress!<BR>Please wait...!</code>"}
else if(dirty==100)
dat = {"<TT>This [src] is dirty!<BR>Please clean it before use!</TT>"}
dat = {"<code>This [src] is dirty!<BR>Please clean it before use!</code>"}
else
var/list/items_counts = new
var/list/items_measures = new
@@ -260,12 +244,13 @@
stop()
return
var/datum/recipe/recipe = select_recipe(available_recipes,src)
var/obj/cooked
var/obj/byproduct
if(!recipe)
var/list/recipes_to_make = choose_recipes()
if(recipes_to_make.len == 1 && recipes_to_make[1][2] == RECIPE_FAIL)
//This only runs if there is a single recipe source to be made and it is a failure (the machine was loaded with only 1 mixing bowl that results in failure OR was directly loaded with ingredients that results in failure).
//If there are multiple sources, this bit gets skipped.
dirty += 1
if(prob(max(10,dirty*5)))
if(prob(max(10,dirty*5))) //chance to get so dirty we require cleaning before next use
if(!wzhzhzh(4))
abort()
return
@@ -274,14 +259,14 @@
muck_finish()
fail()
return
else if(has_extra_item())
else if(has_extra_item()) //if extra items present, break down and require repair before next use
if(!wzhzhzh(4))
abort()
return
broke()
fail()
return
else
else //otherwise just stop without requiring cleaning/repair
if(!wzhzhzh(10))
abort()
return
@@ -289,24 +274,69 @@
fail()
return
else
var/halftime = round(recipe.time/10/2)
if(!wzhzhzh(halftime))
if(!wzhzhzh(5))
abort()
return
if(!wzhzhzh(halftime))
if(!wzhzhzh(5))
abort()
fail()
return
cooked = recipe.make_food(src)
byproduct = recipe.get_byproduct()
stop()
if(cooked)
cooked.forceMove(loc)
for(var/i=1,i<efficiency,i++)
cooked = new cooked.type(loc)
if(byproduct)
new byproduct(loc)
make_recipes(recipes_to_make)
//choose_recipes(): picks out recipes for the machine and any mixing bowls it may contain.
//builds a list of the selected recipes to be made in a later proc by associating the "source" of the ingredients (mixing bowl, machine) with the recipe for that source
/obj/machinery/kitchen_machine/proc/choose_recipes()
var/list/recipes_to_make = list()
for(var/obj/item/mixing_bowl/mb in contents) //if we have mixing bowls present, check each one for possible recipes from its respective contents. Mixing bowls act like a wrapper for recipes and ingredients, isolating them from other ingredients and mixing bowls within a machine.
var/datum/recipe/recipe = select_recipe(GLOB.cooking_recipes[recipe_type], mb)
if(recipe)
recipes_to_make.Add(list(list(mb, recipe)))
else //if the ingredients of the mixing bowl don't make a valid recipe, we return a fail recipe to generate the burned mess
recipes_to_make.Add(list(list(mb, RECIPE_FAIL)))
var/datum/recipe/recipe_src = select_recipe(GLOB.cooking_recipes[recipe_type], src, ignored_items = list(/obj/item/mixing_bowl)) //check the machine's directly-inserted ingredients for possible recipes as well, ignoring the mixing bowls when selecting recipe
if(recipe_src) //if we found a valid recipe for directly-inserted ingredients, add that to our list
recipes_to_make.Add(list(list(src, recipe_src)))
else if(!recipes_to_make.len) //if the machine has no mixing bowls to make recipes from AND also doesn't have a valid recipe of directly-inserted ingredients, return a failure so we can make a burned mess
recipes_to_make.Add(list(list(src, RECIPE_FAIL)))
return recipes_to_make
//make_recipes(recipes_to_make): cycles through the supplied list of recipes and creates each recipe associated with the "source" for that entry
/obj/machinery/kitchen_machine/proc/make_recipes(list/recipes_to_make)
if(!recipes_to_make)
return
var/datum/reagents/temp_reagents = new(500)
for(var/i=1 to recipes_to_make.len) //cycle through each entry on the recipes_to_make list for processing
var/list/L = recipes_to_make[i]
var/obj/source = L[1] //this is the source of the recipe entry (mixing bowl or the machine)
var/datum/recipe/recipe = L[2] //this is the recipe associated with the source (a valid recipe or null)
if(recipe == RECIPE_FAIL) //we have a failure and create a burned mess
//failed recipe
fail()
else //we have a valid recipe to begin making
for(var/obj/O in source.contents) //begin processing the ingredients supplied
if(istype(O, /obj/item/mixing_bowl)) //ignore mixing bowls present among the ingredients in our source (only really applies to machine sourced recipes)
continue
if(O.reagents)
O.reagents.del_reagent("nutriment")
O.reagents.update_total()
O.reagents.trans_to(temp_reagents, O.reagents.total_volume)
qdel(O)
source.reagents.clear_reagents()
for(var/e=1 to efficiency) //upgraded machine? make additional servings and split the ingredient reagents among each serving equally.
var/obj/cooked = new recipe.result()
temp_reagents.trans_to(cooked, temp_reagents.total_volume/efficiency)
cooked.forceMove(loc)
temp_reagents.clear_reagents()
var/obj/byproduct = recipe.get_byproduct() //if the recipe has a byproduct, handle returning that (such as re-usable candy moulds)
if(byproduct)
new byproduct(loc)
if(istype(source, /obj/item/mixing_bowl)) //if the recipe's source was a mixing bowl, make it a little dirtier and return that for re-use.
var/obj/item/mixing_bowl/mb = source
mb.make_dirty(5 * efficiency)
mb.forceMove(loc)
stop()
return
/obj/machinery/kitchen_machine/proc/wzhzhzh(seconds)
for(var/i=1 to seconds)
@@ -318,10 +348,7 @@
/obj/machinery/kitchen_machine/proc/has_extra_item()
for(var/obj/O in contents)
if( \
!istype(O,/obj/item/reagent_containers/food) && \
!istype(O, /obj/item/grown) \
)
if(!is_type_in_list(O, list(/obj/item/reagent_containers/food, /obj/item/grown, /obj/item/mixing_bowl)))
return 1
return 0
@@ -376,19 +403,27 @@
updateUsrDialog()
/obj/machinery/kitchen_machine/proc/fail()
var/obj/item/reagent_containers/food/snacks/badrecipe/ffuu = new(src)
var/amount = 0
for(var/obj/O in contents-ffuu)
for(var/obj/item/mixing_bowl/mb in contents) //fail and remove any mixing bowls present before making the burned mess from the machine itself (to avoid them being destroyed as part of the failure)
mb.fail(src)
mb.forceMove(get_turf(src))
for(var/obj/O in contents)
amount++
if(O.reagents)
if(O.reagents) //this is reagents in inserted objects (like chems in produce)
var/id = O.reagents.get_master_reagent_id()
if(id)
amount+=O.reagents.get_reagent_amount(id)
qdel(O)
if(reagents && reagents.total_volume) //this is directly-added reagents (like water added directly into the machine)
var/id = reagents.get_master_reagent_id()
if(id)
amount += reagents.get_reagent_amount(id)
reagents.clear_reagents()
ffuu.reagents.add_reagent("carbon", amount)
ffuu.reagents.add_reagent("????", amount/10)
ffuu.forceMove(get_turf(src))
if(amount)
var/obj/item/reagent_containers/food/snacks/badrecipe/ffuu = new(src)
ffuu.reagents.add_reagent("carbon", amount)
ffuu.reagents.add_reagent("????", amount/10)
ffuu.forceMove(get_turf(src))
/obj/machinery/kitchen_machine/Topic(href, href_list)
if(..() || panel_open)
@@ -5,7 +5,7 @@
icon = 'icons/obj/kitchen.dmi'
icon_state = "mw"
cook_verbs = list("Microwaving", "Reheating", "Heating")
recipe_type = /datum/recipe/microwave
recipe_type = RECIPE_MICROWAVE
off_icon = "mw"
on_icon = "mw1"
broken_icon = "mwb"
@@ -5,7 +5,7 @@
icon = 'icons/obj/cooking_machines.dmi'
icon_state = "oven_off"
cook_verbs = list("Baking", "Roasting", "Broiling")
recipe_type = /datum/recipe/oven
recipe_type = RECIPE_OVEN
off_icon = "oven_off"
on_icon = "oven_on"
broken_icon = "oven_broke"