Fixes Intellitater crafting deleting AIs (#48451)

* Adds safety requirement checking to crafting

/datum/crafting_recipe now has check_requirements() which will be called once item instances that will be used are collected. If this fails, the crafting will be aborted.

* Prevent populated AI cards from use in crafting.

- Overrides check_requirements for the aitater crafting_recipe, failing it if there is an AI present in the candidate card.
This commit is contained in:
Jordan Brown
2019-12-29 13:20:45 -05:00
committed by ShizCalev
parent 051851f2ae
commit bed37b7bb2
2 changed files with 61 additions and 23 deletions
+44 -23
View File
@@ -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
@@ -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, "<span class='boldwarning'>You can't craft an intelliTater with an AI in the card!</span>")
return FALSE
/datum/crafting_recipe/aispook
name = "intelliLantern"
result = /obj/item/aicard/aispook