mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-12 07:33:34 +01:00
523c09bab9
* Fix issue with cooking recipes requiring reagents * don't spam debug messages with autochef * reagent step processing, other fuckery * fix lint * properly clean up tracked recipes
186 lines
7.0 KiB
Plaintext
186 lines
7.0 KiB
Plaintext
GLOBAL_LIST_EMPTY(pcwj_recipe_dictionary)
|
|
GLOBAL_LIST_EMPTY(pcwj_cookbook_lookup)
|
|
|
|
/**
|
|
* ## ParaCooking With Jane
|
|
*
|
|
* A cooking rework ported from Sojourn and heavily adapted for Para.
|
|
*
|
|
* The recipe datum outlines a list of steps from getting a piece of food from
|
|
* point A to point B.
|
|
*
|
|
* Recipes have clear start and end points. They start with a particular item
|
|
* and end with a particular item. That said, a start item can follow multiple
|
|
* recipes until they eventually diverge as different steps are followed. In the
|
|
* case two recipes have identical steps, the user should be prompted on what
|
|
* their intended result should be. (Donuts vs Bagels)
|
|
*
|
|
* Recipes are loaded at startup. Food items reference it by the recipe_tracker
|
|
* datum.
|
|
*
|
|
* Recipes and their steps are singletons. Cooking processes should never alter
|
|
* them.
|
|
*/
|
|
/datum/cooking/recipe
|
|
/// The type of the cooking container the recipe is performed in.
|
|
var/obj/item/reagent_containers/cooking/container_type
|
|
/// Type path for the product created by the recipe.
|
|
var/product_type
|
|
/// How much of a thing is made per case of the recipe being followed.
|
|
var/product_count = 1
|
|
|
|
// Special variables that must be defined INSTEAD of product_type in order to create reagents instead of an object.
|
|
var/reagent_id
|
|
var/reagent_amount
|
|
|
|
/// Determines if we entirely replace the contents of the food product with the slurry that goes into it.
|
|
var/replace_reagents = FALSE
|
|
|
|
/// Everything appears in the catalog by default.
|
|
var/appear_in_default_catalog = TRUE
|
|
/// The category of the recipe for the cookbook PDA app and other sources of recipe info.
|
|
var/catalog_category = "Miscellaneous"
|
|
|
|
/// A list of [/datum/cooking/recipe_step]s needed to be followed
|
|
/// to create the recipe. Generally steps must be completed in order
|
|
/// for the preparation to be considered valid.
|
|
var/list/steps
|
|
|
|
/datum/cooking/recipe/proc/create_product(datum/cooking/recipe_tracker/tracker)
|
|
var/obj/item/reagent_containers/cooking/container = locateUID(tracker.container_uid)
|
|
|
|
if(!istype(container))
|
|
log_debug("failure to find container when creating recipe product!")
|
|
return
|
|
|
|
// Build up a list of reagents that went into this.
|
|
var/datum/reagents/slurry = new(maximum = 1000000)
|
|
slurry.my_atom = container
|
|
|
|
var/list/applied_steps = tracker.recipes_all_applied_steps[src]
|
|
var/output_count = 1
|
|
for(var/i in 1 to length(tracker.recipes_applied_step_data))
|
|
var/list/applied_step_data = tracker.recipes_applied_step_data[i]
|
|
|
|
if("reagent_id" in applied_step_data)
|
|
var/amount_to_remove = applied_step_data["amount"] * (1 - applied_step_data["reagent_remain_percent"])
|
|
if(!amount_to_remove)
|
|
continue
|
|
container.reagents.remove_reagent(
|
|
applied_step_data["reagent_id"], amount_to_remove, safety = TRUE)
|
|
|
|
if("rating" in applied_step_data)
|
|
output_count = max(output_count, min(3, applied_step_data["rating"]))
|
|
|
|
if(product_type) // Make a regular item
|
|
. = make_product_item(container, slurry, applied_steps, output_count)
|
|
else
|
|
QDEL_LIST_CONTENTS(container.contents)
|
|
container.contents = list()
|
|
|
|
container.reagents.clear_reagents()
|
|
|
|
if(reagent_id)
|
|
container.reagents.add_reagent(reagent_id, reagent_amount)
|
|
|
|
qdel(slurry)
|
|
|
|
/datum/cooking/recipe/proc/make_product_item(obj/item/reagent_containers/cooking/container, datum/reagents/slurry, list/applied_steps, output_count = null)
|
|
if(isnull(output_count))
|
|
output_count = 1
|
|
|
|
if(container.reagents.total_volume)
|
|
#ifdef PCWJ_DEBUG
|
|
log_debug("/recipe/proc/create_product: Transferring container reagents of [container.reagents.total_volume] to slurry of current volume [slurry.total_volume] max volume [slurry.maximum_volume]")
|
|
#endif
|
|
container.reagents.trans_to(slurry, amount=container.reagents.total_volume)
|
|
|
|
// Do reagent filtering on added items and produce
|
|
var/list/exclude_list = list()
|
|
for(var/obj/item/added_item in container.contents)
|
|
var/can_add = TRUE
|
|
var/list/exclude_specific_reagents = list()
|
|
#ifdef PCWJ_DEBUG
|
|
log_debug("/recipe/proc/create_product: Analyzing reagents of [added_item].")
|
|
#endif
|
|
for(var/i in 1 to length(applied_steps))
|
|
var/current_index = applied_steps[i]
|
|
var/datum/cooking/recipe_step = steps[current_index]
|
|
|
|
if(recipe_step in exclude_list)
|
|
continue
|
|
|
|
var/datum/cooking/recipe_step/add_item/add_item_step = recipe_step
|
|
if(istype(add_item_step))
|
|
if(add_item_step.exclude_reagents)
|
|
exclude_specific_reagents |= add_item_step.exclude_reagents
|
|
if(add_item_step.skip_reagents)
|
|
can_add = FALSE
|
|
exclude_list |= recipe_step
|
|
break
|
|
|
|
var/datum/cooking/recipe_step/add_produce/add_produce_step = recipe_step
|
|
if(istype(add_produce_step))
|
|
if(add_produce_step.exclude_reagents)
|
|
exclude_specific_reagents |= add_produce_step.exclude_reagents
|
|
if(add_produce_step.skip_reagents)
|
|
can_add = FALSE
|
|
exclude_list |= recipe_step
|
|
break
|
|
|
|
if(can_add && added_item.reagents)
|
|
if(length(exclude_specific_reagents))
|
|
for(var/id in exclude_specific_reagents)
|
|
added_item.reagents.remove_reagent(id, added_item.reagents.get_reagent_amount(id), safety = TRUE)
|
|
added_item.reagents.trans_to(slurry, amount = added_item.reagents.total_volume)
|
|
|
|
// Purge the contents of the container we no longer need it
|
|
QDEL_LIST_CONTENTS(container.contents)
|
|
|
|
for(var/i in 1 to (product_count * output_count))
|
|
var/obj/item/new_item = new product_type(container)
|
|
. = new_item
|
|
#ifdef PCWJ_DEBUG
|
|
log_debug("/recipe/proc/create_product: Item created with reagents of [new_item.reagents.total_volume]")
|
|
#endif
|
|
if(replace_reagents)
|
|
//Clearing out reagents in data. If initialize hasn't been called, we also null that out here.
|
|
#ifdef PCWJ_DEBUG
|
|
log_debug("/recipe/proc/create_product: Clearing out reagents from the [new_item]")
|
|
#endif
|
|
new_item.reagents.clear_reagents()
|
|
#ifdef PCWJ_DEBUG
|
|
log_debug("/recipe/proc/create_product: Transferring slurry of [slurry.total_volume] to [new_item] of total volume [new_item.reagents.total_volume]")
|
|
#endif
|
|
slurry.copy_to(new_item, amount=slurry.total_volume)
|
|
|
|
/proc/initialize_cooking_recipes()
|
|
GLOB.pcwj_recipe_dictionary.Cut()
|
|
GLOB.pcwj_cookbook_lookup.Cut()
|
|
var/list/recipe_paths = subtypesof(/datum/cooking/recipe)
|
|
for(var/path in recipe_paths)
|
|
var/datum/cooking/recipe/example_recipe = new path()
|
|
if(!example_recipe.container_type)
|
|
continue
|
|
|
|
var/obj/item/reagent_containers/cooking/container_type = example_recipe.container_type
|
|
|
|
LAZYORASSOCLIST(GLOB.pcwj_recipe_dictionary, example_recipe.container_type, example_recipe)
|
|
|
|
if(!example_recipe.appear_in_default_catalog)
|
|
continue
|
|
|
|
if(example_recipe.product_type)
|
|
var/atom/product = example_recipe.product_type
|
|
|
|
var/list/entry = list()
|
|
entry["name"] = product::name
|
|
entry["icon"] = product::icon
|
|
entry["icon_state"] = product::icon_state
|
|
entry["container"] = "[container_type::preposition] \a [container_type::name]"
|
|
entry["instructions"] = list()
|
|
for(var/datum/cooking/recipe_step/step in example_recipe.steps)
|
|
entry["instructions"] += step.get_pda_formatted_desc()
|
|
|
|
LAZYORASSOCLIST(GLOB.pcwj_cookbook_lookup, example_recipe.catalog_category, list(entry))
|