diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm index 3f45d5709ca..40566227c01 100644 --- a/code/datums/components/crafting/crafting.dm +++ b/code/datums/components/crafting/crafting.dm @@ -63,29 +63,48 @@ - -/datum/component/personal_crafting/proc/check_contents(datum/crafting_recipe/R, list/contents) +/** + * Check that the contents of the recipe meet the requirements. + * + * user: The /mob that initated the crafting. + * R: The /datum/crafting_recipe being attempted. + * contents: List of items to search for R's reqs. + */ +/datum/component/personal_crafting/proc/check_contents(mob/user, datum/crafting_recipe/R, list/contents) + var/list/item_instances = contents["instances"] contents = contents["other"] - main_loop: - for(var/A in R.reqs) - var/needed_amount = R.reqs[A] - for(var/B in contents) - if(ispath(B, A)) - if (R.blacklist.Find(B)) - continue - if(contents[B] >= R.reqs[A]) - continue main_loop - else - needed_amount -= contents[B] - if(needed_amount <= 0) - continue main_loop - else - continue + + var/list/requirements_list = list() + + // Process all requirements + for(var/requirement_path in R.reqs) + // Check we have the appropriate amount available in the contents list + var/needed_amount = R.reqs[requirement_path] + for(var/content_item_path in contents) + // Right path and not blacklisted + if(!ispath(content_item_path, requirement_path) || R.blacklist.Find(requirement_path)) + continue + + needed_amount -= contents[content_item_path] + if(needed_amount <= 0) + break + + if(needed_amount > 0) return FALSE - for(var/A in R.chem_catalysts) - if(contents[A] < R.chem_catalysts[A]) + + // Store the instances of what we will use for R.check_requirements() for requirement_path + var/list/instances_list = list() + for(var/instance_path in item_instances) + if(ispath(instance_path, requirement_path)) + instances_list += item_instances[instance_path] + + requirements_list[requirement_path] = instances_list + + for(var/requirement_path in R.chem_catalysts) + if(contents[requirement_path] < R.chem_catalysts[requirement_path]) return FALSE - return TRUE + + return R.check_requirements(user, requirements_list) /datum/component/personal_crafting/proc/get_environment(mob/user, list/blacklist = null) . = list() @@ -113,9 +132,11 @@ . = list() .["tool_behaviour"] = list() .["other"] = list() + .["instances"] = list() for(var/obj/item/I in get_environment(user)) if(I.flags_1 & HOLOGRAM_1) continue + .["instances"][I.type] += I if(istype(I, /obj/item/stack)) var/obj/item/stack/S = I .["other"][I.type] += S.amount @@ -164,11 +185,11 @@ /datum/component/personal_crafting/proc/construct_item(mob/user, datum/crafting_recipe/R) var/list/contents = get_surroundings(user) var/send_feedback = 1 - if(check_contents(R, contents)) + if(check_contents(user, R, contents)) if(check_tools(user, R, contents)) if(do_after(user, R.time, target = user)) contents = get_surroundings(user) - if(!check_contents(R, contents)) + if(!check_contents(user, R, contents)) return ", missing component." if(!check_tools(user, R, contents)) return ", missing tool." @@ -343,7 +364,7 @@ if((R.category != cur_category) || (R.subcategory != cur_subcategory)) continue - craftability["[REF(R)]"] = check_contents(R, surroundings) + craftability["[REF(R)]"] = check_contents(user, R, surroundings) data["craftability"] = craftability return data diff --git a/code/datums/components/crafting/recipes.dm b/code/datums/components/crafting/recipes.dm index e3d242d663e..df4b78597ae 100644 --- a/code/datums/components/crafting/recipes.dm +++ b/code/datums/components/crafting/recipes.dm @@ -16,6 +16,15 @@ if(!(result in reqs)) blacklist += result +/** + * Run custom pre-craft checks for this recipe + * + * user: The /mob that initiated the crafting + * collected_requirements: A list of lists of /obj/item instances that satisfy reqs. Top level list is keyed by requirement path. + */ +/datum/crafting_recipe/proc/check_requirements(mob/user, list/collected_requirements) + return TRUE + /datum/crafting_recipe/pin_removal name = "Pin Removal" result = /obj/item/gun @@ -713,6 +722,14 @@ /obj/item/stack/cable_coil = 5) category = CAT_MISC +/datum/crafting_recipe/aitater/check_requirements(mob/user, list/collected_requirements) + var/obj/item/aicard/aicard = collected_requirements[/obj/item/aicard][1] + if(!aicard.AI) + return TRUE + + to_chat(user, "You can't craft an intelliTater with an AI in the card!") + return FALSE + /datum/crafting_recipe/aispook name = "intelliLantern" result = /obj/item/aicard/aispook