mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-20 19:44:09 +01:00
Fix issue with cooking recipes requiring reagents (#30611)
* 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
This commit is contained in:
committed by
GitHub
parent
87a1e11667
commit
523c09bab9
@@ -59,20 +59,15 @@ GLOBAL_LIST_EMPTY(pcwj_cookbook_lookup)
|
||||
|
||||
var/list/applied_steps = tracker.recipes_all_applied_steps[src]
|
||||
var/output_count = 1
|
||||
// Remember this is not necessarily a consecutive list of step indexes
|
||||
// Optional steps may have been skipped
|
||||
for(var/i in 1 to length(applied_steps))
|
||||
var/current_index = applied_steps[i]
|
||||
var/datum/cooking/recipe_step/recipe_step = steps[current_index]
|
||||
for(var/i in 1 to length(tracker.recipes_applied_step_data))
|
||||
var/list/applied_step_data = tracker.recipes_applied_step_data[i]
|
||||
|
||||
// Filter out reagents based on settings
|
||||
var/datum/cooking/recipe_step/add_reagent/add_reagent_step = recipe_step
|
||||
if(istype(add_reagent_step))
|
||||
var/amount_to_remove = add_reagent_step.amount * (1 - add_reagent_step.remain_percent)
|
||||
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(add_reagent_step.reagent_id, amount_to_remove, safety = TRUE)
|
||||
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"]))
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/// A single attempt to perform a step in a recipe.
|
||||
/// These are created in a recipe tracker and not kept around.
|
||||
/// This exists only to make the bookkeeping around recipe tracking easier.
|
||||
/datum/cooking/step_attempt
|
||||
var/conditions_met
|
||||
var/current_step_index
|
||||
var/datum/cooking/recipe/recipe
|
||||
var/datum/cooking/recipe_step/recipe_step
|
||||
|
||||
/datum/cooking/step_attempt/New(
|
||||
datum/cooking/recipe/recipe,
|
||||
datum/cooking/recipe_step/recipe_step,
|
||||
current_step_index,
|
||||
conditions_met
|
||||
)
|
||||
src.recipe = recipe
|
||||
src.recipe_step = recipe_step
|
||||
src.current_step_index = current_step_index
|
||||
src.conditions_met = conditions_met
|
||||
|
||||
/// A recipe tracker is an abstract representation of the progress that a
|
||||
/// cooking container has made towards any of its possible recipe outcomes.
|
||||
///
|
||||
@@ -41,7 +61,7 @@
|
||||
/// Wrapper function for analyzing process_item internally.
|
||||
/datum/cooking/recipe_tracker/proc/process_item_wrap(mob/user, obj/used)
|
||||
#ifdef PCWJ_DEBUG
|
||||
log_debug("/datum/cooking/recipe_tracker/proc/process_item_wrap called!")
|
||||
log_debug("/datum/cooking/recipe_tracker/proc/process_item_wrap([user], [used])")
|
||||
#endif
|
||||
|
||||
var/response = process_item(user, used)
|
||||
@@ -74,44 +94,27 @@
|
||||
// TODO: I *hate* passing in a user here and want to move all the necessary
|
||||
// UI interactions (selecting which recipe to complete, selecting which step
|
||||
// to perform) to be moved somewhere else entirely.
|
||||
var/list/valid_steps = list()
|
||||
var/list/valid_recipes = list()
|
||||
var/list/completed_recipes = list()
|
||||
var/list/silent_recipes = list()
|
||||
var/list/attempted_step_per_recipe = list()
|
||||
var/list/step_datas = list()
|
||||
var/list/step_attempts = list()
|
||||
var/completed_steps = 0
|
||||
|
||||
for(var/datum/cooking/recipe/recipe in recipes_last_completed_step)
|
||||
var/current_idx = recipes_last_completed_step[recipe]
|
||||
var/datum/cooking/recipe_step/next_step
|
||||
|
||||
var/match = FALSE
|
||||
do
|
||||
next_step = recipe.steps[++current_idx]
|
||||
var/conditions = next_step.check_conditions_met(used, src)
|
||||
if(conditions == PCWJ_CHECK_VALID)
|
||||
LAZYADD(valid_steps[next_step.type], next_step)
|
||||
LAZYADD(valid_recipes[next_step.type], recipe)
|
||||
attempted_step_per_recipe[recipe] = current_idx
|
||||
match = TRUE
|
||||
break
|
||||
else if(conditions == PCWJ_CHECK_SILENT)
|
||||
LAZYADD(silent_recipes, recipe)
|
||||
var/conditions_met = next_step.check_conditions_met(used, src)
|
||||
if(conditions_met == PCWJ_CHECK_VALID || conditions_met == PCWJ_CHECK_SILENT)
|
||||
step_attempts += new/datum/cooking/step_attempt(
|
||||
recipe, next_step, current_idx, conditions_met)
|
||||
while(next_step && next_step.optional && current_idx <= length(recipe.steps))
|
||||
|
||||
if(match)
|
||||
LAZYOR(recipes_all_applied_steps[recipe], current_idx)
|
||||
if(length(recipe.steps) == current_idx)
|
||||
completed_recipes |= recipe
|
||||
|
||||
if(!length(valid_steps))
|
||||
if(length(silent_recipes))
|
||||
return PCWJ_PARTIAL_SUCCESS
|
||||
if(!length(step_attempts))
|
||||
return PCWJ_NO_STEPS
|
||||
|
||||
var/list/recipes_with_completed_steps = list()
|
||||
var/list/step_data
|
||||
var/complete_steps = 0
|
||||
for(var/step_type in valid_steps)
|
||||
for(var/datum/cooking/step_attempt/step_attempt in step_attempts)
|
||||
// For each valid step type we only call follow_step() once since it's
|
||||
// pointless to e.g. add an item to the container more than once.
|
||||
//
|
||||
@@ -124,21 +127,33 @@
|
||||
// for now, we do nothing, and just watch out for situations where two
|
||||
// different recipe steps with incompatible end states are valid with
|
||||
// the same object.
|
||||
var/datum/cooking/recipe_step/sample_step = valid_steps[step_type][1]
|
||||
step_data = sample_step.follow_step(used, src)
|
||||
step_reaction_message = step_data["message"]
|
||||
if(!(step_attempt.recipe_step.type in step_datas))
|
||||
var/step_data = step_attempt.recipe_step.follow_step(used, src)
|
||||
if(islist(step_data))
|
||||
step_datas[step_attempt.recipe_step.type] = step_data
|
||||
step_reaction_message = step_datas[step_attempt.recipe_step.type]["message"]
|
||||
|
||||
for(var/i in 1 to length(valid_recipes[step_type]))
|
||||
var/datum/cooking/recipe/recipe = valid_recipes[step_type][i]
|
||||
var/datum/cooking/recipe_step/recipe_step = valid_steps[step_type][i]
|
||||
if(recipe_step.is_complete(used, src, step_data))
|
||||
recipes_last_completed_step[recipe] = attempted_step_per_recipe[recipe]
|
||||
recipes_with_completed_steps |= recipe
|
||||
complete_steps++
|
||||
var/previous_step = recipes_last_completed_step[step_attempt.recipe]
|
||||
if(step_attempt.recipe_step.is_complete(used, src, step_datas[step_attempt.recipe_step.type]))
|
||||
recipes_last_completed_step[step_attempt.recipe] = step_attempt.current_step_index
|
||||
LAZYOR(recipes_all_applied_steps[step_attempt.recipe], step_attempt.current_step_index)
|
||||
completed_steps++
|
||||
|
||||
if(step_attempt.recipe_step == step_attempt.recipe.steps[length(step_attempt.recipe.steps)])
|
||||
completed_recipes += step_attempt.recipe
|
||||
else
|
||||
recipes_last_completed_step[step_attempt.recipe] = previous_step
|
||||
|
||||
if(length(step_datas) > 1)
|
||||
var/list/types = list()
|
||||
for(var/step_type in step_datas)
|
||||
types += "[step_type]"
|
||||
log_debug("More than one valid step data at the same step, this shouldn't happen. Valid steps: [jointext(types, ", ")]")
|
||||
|
||||
var/obj/item/reagent_containers/cooking/container = locateUID(container_uid)
|
||||
if(complete_steps)
|
||||
recipes_applied_step_data += list(step_data)
|
||||
if(completed_steps)
|
||||
var/list/first_applied_step_data = step_datas[1]
|
||||
recipes_applied_step_data += list(step_datas[first_applied_step_data])
|
||||
|
||||
// Empty out the stove data here so that it can be reused from zero for
|
||||
// other cooking steps, as well as to prevent cheatiness where a recipe
|
||||
@@ -147,15 +162,11 @@
|
||||
if(container)
|
||||
container.clear_cooking_data()
|
||||
|
||||
if("signal" in step_data)
|
||||
SEND_SIGNAL(container, step_data["signal"])
|
||||
if("signal" in first_applied_step_data)
|
||||
SEND_SIGNAL(container, first_applied_step_data["signal"])
|
||||
else
|
||||
return PCWJ_PARTIAL_SUCCESS
|
||||
|
||||
for(var/recipe in recipes_last_completed_step)
|
||||
if(!(recipe in recipes_with_completed_steps))
|
||||
recipes_last_completed_step -= recipe
|
||||
|
||||
var/datum/cooking/recipe/recipe_to_complete
|
||||
if(length(completed_recipes))
|
||||
if(length(completed_recipes) == 1)
|
||||
@@ -180,4 +191,11 @@
|
||||
|
||||
return PCWJ_COMPLETE
|
||||
|
||||
// any recipes that have fewer completed steps than the number
|
||||
// of steps we've actually accomplished shouldn't be considered
|
||||
var/completed_step_count = length(recipes_applied_step_data)
|
||||
for(var/recipe in recipes_last_completed_step)
|
||||
if(!(recipe in recipes_all_applied_steps) || length(recipes_all_applied_steps[recipe]) < completed_step_count)
|
||||
recipes_last_completed_step.Remove(recipe)
|
||||
|
||||
return PCWJ_SUCCESS
|
||||
|
||||
@@ -35,6 +35,7 @@ RESTRICT_TYPE(/datum/cooking/recipe_step)
|
||||
/// Special function to check if the step has been satisfied. Sometimes just
|
||||
/// following the step is enough, but not always.
|
||||
/datum/cooking/recipe_step/proc/is_complete(obj/added_item, datum/cooking/recipe_tracker/tracker, list/step_data)
|
||||
SHOULD_BE_PURE(TRUE)
|
||||
return TRUE
|
||||
|
||||
/// Return a human readable description of the recipe step as an instruction to the reader.
|
||||
|
||||
@@ -79,12 +79,12 @@ RESTRICT_TYPE(/datum/cooking/recipe_step/add_reagent)
|
||||
/datum/cooking/recipe_step/add_reagent/follow_step(obj/used_item, datum/cooking/recipe_tracker/tracker)
|
||||
var/obj/item/reagent_containers/our_item = used_item
|
||||
if(!istype(our_item))
|
||||
return list()
|
||||
return
|
||||
|
||||
var/obj/item/container = locateUID(tracker.container_uid)
|
||||
var/trans = our_item.reagents.trans_to(container, our_item.amount_per_transfer_from_this)
|
||||
|
||||
return list(message = "You transfer [trans] units to \the [container].")
|
||||
return list("message" = "You transfer [trans] units to \the [container].", "amount" = amount, "reagent_remain_percent" = remain_percent, "reagent_id" = reagent_id)
|
||||
|
||||
/datum/cooking/recipe_step/add_reagent/is_complete(obj/used_item, datum/cooking/recipe_tracker/tracker, list/step_data)
|
||||
var/obj/item/container = locateUID(tracker.container_uid)
|
||||
|
||||
@@ -14,16 +14,18 @@
|
||||
return
|
||||
|
||||
/datum/cooking/recipe_step/use_machine/check_conditions_met(obj/used_item, datum/cooking/recipe_tracker/tracker)
|
||||
var/obj/item/reagent_containers/cooking/container = locateUID(tracker.container_uid)
|
||||
|
||||
if(container.get_cooker_time(cooker_surface_name, temperature) >= time)
|
||||
return PCWJ_CHECK_VALID
|
||||
|
||||
if(istype(used_item, machine_type))
|
||||
return PCWJ_CHECK_SILENT
|
||||
|
||||
return PCWJ_CHECK_INVALID
|
||||
|
||||
/datum/cooking/recipe_step/use_machine/is_complete(obj/added_item, datum/cooking/recipe_tracker/tracker, list/step_data)
|
||||
var/obj/item/reagent_containers/cooking/container = locateUID(tracker.container_uid)
|
||||
if(istype(container) && container.get_cooker_time(cooker_surface_name, temperature) >= time)
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
/datum/cooking/recipe_step/use_machine/follow_step(obj/used_item, datum/cooking/recipe_tracker/tracker, mob/user)
|
||||
var/list/step_data = list(target = used_item.UID())
|
||||
var/obj/item/reagent_containers/cooking/container = locateUID(tracker.container_uid)
|
||||
|
||||
Reference in New Issue
Block a user