Merge pull request #3094 from CHOMPStationBot/upstream-merge-11553

[MIRROR] [MIRROR] Refactors crafting to support requirement alternatives
This commit is contained in:
Nadyr
2021-10-22 20:01:37 -04:00
committed by GitHub
6 changed files with 321 additions and 270 deletions

View File

@@ -62,55 +62,7 @@
del_reqs - takes recipe and a user, loops over the recipes reqs var and tries to find everything in the list make by get_environment and delete it/add to parts list, then returns the said list
*/
/**
* 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(atom/a, datum/crafting_recipe/R, list/contents)
var/list/item_instances = contents["instances"]
var/list/machines = contents["machinery"]
contents = contents["other"]
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(content_item_path))
continue
needed_amount -= contents[content_item_path]
if(needed_amount <= 0)
break
if(needed_amount > 0)
return FALSE
// 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
for(var/machinery_path in R.machinery)
if(!machines[machinery_path])//We don't care for volume with machines, just if one is there or not
return FALSE
return R.check_requirements(a, requirements_list)
// Returns a list of objects available
/datum/component/personal_crafting/proc/get_environment(atom/a, list/blacklist = null, radius_range = 1)
. = list()
@@ -122,13 +74,13 @@
continue
. += AM
// Returns an associative list containing the types of tools available, and the paths of objects available
/datum/component/personal_crafting/proc/get_surroundings(atom/a, list/blacklist=null)
. = list()
.["tool_qualities"] = list()
.["other"] = list()
.["instances"] = list()
.["machinery"] = list()
.["tool_qualities"] = list() // List of tool types available
.["other"] = list() // List of reagents/material stacks available
.["instances"] = list() // List of /obj/items available, maybe?
.["machinery"] = list() // List of /obj/machinery available
for(var/obj/object in get_environment(a, blacklist))
if(isitem(object))
var/obj/item/item = object
@@ -150,11 +102,55 @@
else if (istype(object, /obj/machinery))
LAZYADDASSOCLIST(.["machinery"], object.type, object)
/**
* 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(atom/a, datum/crafting_recipe/R, list/contents)
var/list/item_instances = contents["instances"]
contents = contents["other"]
var/list/requirements_list = list()
// Process all requirements
for(var/list/requirement in R.reqs)
var/satisfied = FALSE
for(var/requirement_path in requirement)
// Check we have the appropriate amount available in the contents list
var/needed_amount = requirement[requirement_path]
for(var/content_item_path in contents)
// Right path and not blacklisted
if(!ispath(content_item_path, requirement_path) || R.blacklist.Find(content_item_path))
continue
needed_amount -= contents[content_item_path]
if(needed_amount <= 0)
break
if(needed_amount > 0)
continue
// 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
satisfied = TRUE
break
if(!satisfied)
return FALSE
return R.check_requirements(a, requirements_list)
/// Returns a boolean on whether the tool requirements of the input recipe are satisfied by the input source and surroundings.
/datum/component/personal_crafting/proc/check_tools(atom/source, datum/crafting_recipe/recipe, list/surroundings)
if(!length(recipe.tool_behaviors) && !length(recipe.tool_paths))
/datum/component/personal_crafting/proc/check_tools(atom/source, datum/crafting_recipe/R, list/surroundings)
if(!length(R.tool_behaviors) && !length(R.tool_paths))
return TRUE
var/list/available_tools = list()
var/list/present_qualities = list()
@@ -176,50 +172,70 @@
for(var/path in surroundings["other"])
available_tools[path] = TRUE
for(var/required_quality in recipe.tool_behaviors)
for(var/required_quality in R.tool_behaviors)
if(present_qualities[required_quality])
continue
return FALSE
for(var/required_path in recipe.tool_paths)
var/found_this_tool = FALSE
for(var/tool_path in available_tools)
if(!ispath(required_path, tool_path))
continue
found_this_tool = TRUE
break
if(found_this_tool)
for(var/required_path in R.tool_paths)
if(is_path_in_list(required_path, available_tools))
continue
return FALSE
return TRUE
/datum/component/personal_crafting/proc/check_reagents(atom/source, datum/crafting_recipe/R, list/surroundings)
var/list/reagents = surroundings["other"]
for(var/requirement_path in R.chem_catalysts)
if(reagents[requirement_path] < R.chem_catalysts[requirement_path])
return FALSE
return TRUE
/datum/component/personal_crafting/proc/check_machinery(atom/source, datum/crafting_recipe/R, list/surroundings)
var/list/machines = surroundings["machinery"]
for(var/machinery_path in R.machinery)
if(!machines[machinery_path])//We don't care for volume with machines, just if one is there or not
return FALSE
return TRUE
/datum/component/personal_crafting/proc/check_requirements(atom/source, datum/crafting_recipe/R, list/surroundings)
if(!check_contents(source, R, surroundings))
return ", missing component."
if(!check_tools(source, R, surroundings))
return ", missing tool."
if(!check_reagents(source, R, surroundings))
return ", missing reagents."
if(!check_machinery(source, R, surroundings))
return ", missing machinery."
return
/datum/component/personal_crafting/proc/construct_item(atom/a, datum/crafting_recipe/R)
var/list/contents = get_surroundings(a,R.blacklist)
var/list/surroundings = get_surroundings(a,R.blacklist)
// var/send_feedback = 1
if(check_contents(a, R, contents))
if(check_tools(a, R, contents))
if(R.one_per_turf)
for(var/content in get_turf(a))
if(istype(content, R.result))
return ", object already present."
//If we're a mob we'll try a do_after; non mobs will instead instantly construct the item
if(ismob(a) && !do_after(a, R.time, target = a))
return "."
contents = get_surroundings(a,R.blacklist)
if(!check_contents(a, R, contents))
return ", missing component."
if(!check_tools(a, R, contents))
return ", missing tool."
var/list/parts = del_reqs(R, a)
var/atom/movable/I = new R.result (get_turf(a.loc))
I.CheckParts(parts, R)
// if(send_feedback)
// SSblackbox.record_feedback("tally", "object_crafted", 1, I.type)
return I //Send the item back to whatever called this proc so it can handle whatever it wants to do with the new item
return ", missing tool."
return ", missing component."
. = check_requirements(a, R, surroundings)
if(.)
return
if(R.one_per_turf)
for(var/content in get_turf(a))
if(istype(content, R.result))
return ", object already present."
//If we're a mob we'll try a do_after; non mobs will instead instantly construct the item
if(ismob(a) && !do_after(a, R.time, target = a))
return "."
surroundings = get_surroundings(a, R.blacklist)
. = check_requirements(a, R, surroundings)
if(.)
return
var/list/parts = del_reqs(R, a)
var/atom/movable/I = new R.result (get_turf(a.loc))
I.CheckParts(parts, R)
// if(send_feedback)
// SSblackbox.record_feedback("tally", "object_crafted", 1, I.type)
return I //Send the item back to whatever called this proc so it can handle whatever it wants to do with the new item
/*Del reqs works like this:
@@ -246,119 +262,108 @@
*/
/datum/component/personal_crafting/proc/del_reqs(datum/crafting_recipe/R, atom/a)
var/list/surroundings
var/list/Deletion = list()
. = list()
var/data
var/amt
var/list/surroundings = get_environment(a)
var/list/parts = list("items" = list())
if(R.get_parts_reagents_volume())
parts["reagents"] = new /datum/reagents(R.get_parts_reagents_volume()) // Datums don't have create_reagents()
var/list/requirements = list()
if(R.reqs)
requirements += R.reqs
for(var/list/L in R.reqs)
requirements += L
if(R.machinery)
requirements += R.machinery
main_loop:
for(var/path_key in requirements)
amt = R.reqs[path_key] || R.machinery[path_key]
if(!amt)//since machinery can have 0 aka CRAFTING_MACHINERY_USE - i.e. use it, don't consume it!
continue main_loop
surroundings = get_environment(a, R.blacklist)
surroundings -= Deletion
if(ispath(path_key, /datum/reagent))
var/datum/reagent/RG = new path_key
var/datum/reagent/RGNT
while(amt > 0)
var/obj/item/weapon/reagent_containers/RC = locate() in surroundings
RG = RC.reagents.get_reagent(path_key)
if(RG)
if(!locate(RG.type) in Deletion)
Deletion += new RG.type()
if(RG.volume > amt)
RG.volume -= amt
data = RG.data
RC.reagents.conditional_update(RC)
RG = locate(RG.type) in Deletion
RG.volume = amt
RG.data += data
continue main_loop
else
surroundings -= RC
amt -= RG.volume
RC.reagents.reagent_list -= RG
RC.reagents.conditional_update(RC)
RGNT = locate(RG.type) in Deletion
RGNT.volume += RG.volume
RGNT.data += RG.data
qdel(RG)
SEND_SIGNAL(RC.reagents, COMSIG_REAGENTS_CRAFTING_PING) // - [] TODO: Make this entire thing less spaghetti
else
surroundings -= RC
else if(ispath(path_key, /obj/item/stack))
var/obj/item/stack/S
var/obj/item/stack/SD
while(amt > 0)
S = locate(path_key) in surroundings
if(S.get_amount() >= amt)
if(!locate(S.type) in Deletion)
SD = new S.type()
Deletion += SD
S.use(amt)
SD = locate(S.type) in Deletion
SD.add(amt)
continue main_loop
else
amt -= S.get_amount()
if(!locate(S.type) in Deletion)
Deletion += S
else
data = S.get_amount()
S = locate(S.type) in Deletion
S.add(data)
surroundings -= S
else
var/atom/movable/I
while(amt > 0)
I = locate(path_key) in surroundings
Deletion += I
surroundings -= I
amt--
var/list/partlist = list(R.parts.len)
for(var/M in R.parts)
partlist[M] = R.parts[M]
for(var/part in R.parts)
if(istype(part, /datum/reagent))
var/datum/reagent/RG = locate(part) in Deletion
if(RG.volume > partlist[part])
RG.volume = partlist[part]
. += RG
Deletion -= RG
// Try to find everything that was actually used to craft
for(var/path_key in requirements)
var/amt = requirements[path_key]
if(amt <= 0)//since machinery can have 0 aka CRAFTING_MACHINERY_USE - i.e. use it, don't consume it!
continue
else if(istype(part, /obj/item/stack))
var/obj/item/stack/ST = locate(part) in Deletion
if(ST.get_amount() > partlist[part])
ST.set_amount(partlist[part])
. += ST
Deletion -= ST
continue
else
while(partlist[part] > 0)
var/atom/movable/AM = locate(part) in Deletion
. += AM
Deletion -= AM
partlist[part] -= 1
while(Deletion.len)
var/DL = Deletion[Deletion.len]
Deletion.Cut(Deletion.len)
// Snowflake handling of reagent containers and storage atoms.
// If we consumed them in our crafting, we should dump their contents out before qdeling them.
if(istype(DL, /obj/item/weapon/reagent_containers))
var/obj/item/weapon/reagent_containers/container = DL
container.reagents.clear_reagents()
// container.reagents.expose(container.loc, TOUCH)
else if(istype(DL, /obj/item/weapon/storage))
var/obj/item/weapon/storage/container = DL
container.spill()
container.close_all()
qdel(DL)
// If the path is in R.parts, we want to grab those to stuff into the product
var/amt_to_transfer = 0
if(is_path_in_list(path_key, R.parts))
amt_to_transfer = R.parts[path_key]
// Reagent: gotta go sniffing in all the beakers
if(ispath(path_key, /datum/reagent))
var/datum/reagent/reagent = path_key
var/id = initial(reagent.id)
for(var/obj/item/weapon/reagent_containers/RC in surroundings)
// Found everything we need
if(amt <= 0 && amt_to_transfer <= 0)
break
// If we need to keep any to put in the new object, pull it out
if(amt_to_transfer > 0)
var/A = RC.reagents.trans_id_to(parts["reagents"], id, amt_to_transfer)
amt_to_transfer -= A
amt -= A
// If we need to consume some amount of it
if(amt > 0)
var/datum/reagent/RG = RC.reagents.get_reagent(id)
var/A = min(RG.volume, amt)
RC.reagents.remove_reagent(id, A)
amt -= A
SEND_SIGNAL(RC.reagents, COMSIG_REAGENTS_CRAFTING_PING)
// Material stacks may have to accumulate across multiple stacks
else if(ispath(path_key, /obj/item/stack))
for(var/obj/item/stack/S in surroundings)
if(amt <= 0 && amt_to_transfer <= 0)
break
// This could put 50 stacks in an object but frankly so long as the amount's right we don't care
if(amt_to_transfer > 0)
var/obj/item/stack/split = S.split(amt_to_transfer)
if(istype(split))
parts["items"] += split
amt_to_transfer -= split.get_amount()
amt -= split.get_amount()
if(amt > 0)
var/A = min(amt, S.get_amount())
if(S.use(A))
amt -= A
else // Just a regular item. Find them all and delete them
for(var/atom/movable/I in surroundings)
if(amt <= 0 && amt_to_transfer <= 0)
break
if(!istype(I, path_key))
continue
// Special case: the reagents may be needed for other recipes
if(istype(I, /obj/item/weapon/reagent_containers))
var/obj/item/weapon/reagent_containers/RC = I
if(RC.reagents.total_volume > 0)
continue
// We're using it for something
amt--
// Prepare to stuff inside product, don't delete it
if(is_path_in_list(path_key, parts))
parts["items"] += I
amt_to_transfer--
continue
// Snowflake handling of reagent containers and storage atoms.
// If we consumed them in our crafting, we should dump their contents out before qdeling them.
if(istype(I, /obj/item/weapon/reagent_containers))
var/obj/item/weapon/reagent_containers/container = I
container.reagents.clear_reagents()
// container.reagents.expose(container.loc, TOUCH)
else if(istype(I, /obj/item/weapon/storage))
var/obj/item/weapon/storage/container = I
container.spill()
container.close_all()
qdel(I)
return parts
/datum/component/personal_crafting/proc/component_ui_interact(source, location, control, params, user)
// SIGNAL_HANDLER
@@ -487,10 +492,14 @@
var/list/tool_list = list()
var/list/catalyst_text = list()
for(var/atom/req_atom as anything in R.reqs)
//We just need the name, so cheat-typecast to /atom for speed (even tho Reagents are /datum they DO have a "name" var)
//Also these are typepaths so sadly we can't just do "[a]"
req_text += "[R.reqs[req_atom]] [initial(req_atom.name)]"
for(var/list/req in R.reqs)
var/list/L = list()
for(var/atom/req_atom as anything in req)
//We just need the name, so cheat-typecast to /atom for speed (even tho Reagents are /datum they DO have a "name" var)
//Also these are typepaths so sadly we can't just do "[a]"
L += "[req[req_atom]] [initial(req_atom.name)]"
req_text += L.Join(" OR ")
for(var/obj/machinery/content as anything in R.machinery)
req_text += "[R.reqs[content]] [initial(content.name)]"
if(R.additional_req_text)

View File

@@ -12,21 +12,30 @@
*/
/atom/proc/CheckParts(list/parts_list, datum/crafting_recipe/R)
SEND_SIGNAL(src, COMSIG_ATOM_CHECKPARTS, parts_list, R)
if(parts_list)
for(var/A in parts_list)
if(istype(A, /datum/reagent))
if(!reagents)
reagents = new()
reagents.reagent_list.Add(A)
reagents.conditional_update()
else if(ismovable(A))
var/atom/movable/M = A
if(isliving(M.loc))
var/mob/living/L = M.loc
L.unEquip(M, target = src)
else
M.forceMove(src)
SEND_SIGNAL(M, COMSIG_ATOM_USED_IN_CRAFT, src)
if(LAZYLEN(parts_list))
if(istype(parts_list["reagents"], /datum/reagents))
var/datum/reagents/RG = parts_list["reagents"]
if(istype(reagents))
RG.trans_to_holder(reagents, RG.total_volume)
else
reagents = RG
RG.my_atom = src
reagents.conditional_update()
for(var/atom/movable/M as anything in parts_list["items"])
if(isliving(M.loc))
var/mob/living/L = M.loc
L.unEquip(M, target = src)
else
M.forceMove(src)
SEND_SIGNAL(M, COMSIG_ATOM_USED_IN_CRAFT, src)
var/list/L = parts_list["reagents"]
if(LAZYLEN(L))
L.Cut()
L = parts_list["items"]
if(LAZYLEN(L))
L.Cut()
parts_list.Cut()
/obj/machinery/CheckParts(list/parts_list)

View File

@@ -47,3 +47,28 @@
/datum/crafting_recipe/proc/on_craft_completion(mob/user, atom/result)
return
// Computes the total reagents volume
/datum/crafting_recipe/proc/get_parts_reagents_volume()
. = 0
for(var/list/L in parts)
for(var/path in L)
if(ispath(path, /datum/reagent))
. += L[path]
// Locate one of the things that set the material type, and update it from the default (glass)
/datum/crafting_recipe/spear/on_craft_completion(mob/user, atom/result)
var/obj/item/weapon/material/M
for(var/path in parts)
var/obj/item/weapon/material/N = locate(path) in result
if(istype(N, path))
if(!istype(M))
M = N
else
N.forceMove(get_turf(result))
if(!istype(M))
return
var/obj/item/weapon/material/twohanded/spear/S = result
S.set_material(M.material.name)
qdel(M)

View File

@@ -1,14 +1,14 @@
/datum/crafting_recipe/cloth
name = "Cloth bolt"
result = /obj/item/stack/material/cloth
reqs = list(/obj/item/stack/material/fiber = 3)
reqs = list(list(/obj/item/stack/material/fiber = 3))
time = 40
category = CAT_PRIMAL
/datum/crafting_recipe/crude_bandage
name = "Crude bandages (x10)"
result = /obj/item/stack/medical/crude_pack
reqs = list(/obj/item/stack/material/cloth = 2)
reqs = list(list(/obj/item/stack/material/cloth = 2))
time = 40
category = CAT_PRIMAL
@@ -20,8 +20,8 @@
name = "primitive clothes"
result = /obj/item/clothing/under/primitive
reqs = list(
/obj/item/stack/material/fiber = 4,
/obj/item/stack/material/cloth = 6
list(/obj/item/stack/material/fiber = 4),
list(/obj/item/stack/material/cloth = 6)
)
time = 90
category = CAT_CLOTHING
@@ -30,8 +30,8 @@
name = "primitive shoes"
result = /obj/item/clothing/shoes/primitive
reqs = list(
/obj/item/stack/material/fiber = 2,
/obj/item/stack/material/cloth = 3
list(/obj/item/stack/material/fiber = 2),
list(/obj/item/stack/material/cloth = 3)
)
time = 60
category = CAT_CLOTHING

View File

@@ -2,10 +2,10 @@
name = "Wooden Shovel"
result = /obj/item/weapon/shovel/wood
reqs = list(
/obj/item/stack/material/stick = 5,
/obj/item/stack/material/wood = 1,
/obj/item/stack/material/fiber = 3,
/obj/item/stack/material/flint = 1
list(/obj/item/stack/material/stick = 5),
list(/obj/item/stack/material/wood = 1),
list(/obj/item/stack/material/fiber = 3),
list(/obj/item/stack/material/flint = 1)
)
time = 120
category = CAT_WEAPONRY
@@ -15,7 +15,7 @@
name = "stone blade"
result = /obj/item/weapon/material/knife/stone
reqs = list(
/obj/item/stack/material/flint = 2
list(/obj/item/stack/material/flint = 2)
)
time = 60
category = CAT_WEAPONRY
@@ -25,10 +25,10 @@
name = "stone knife"
result = /obj/item/weapon/material/knife/stone/wood
reqs = list(
/obj/item/weapon/material/knife/stone = 1,
/obj/item/stack/material/flint = 1,
/obj/item/stack/material/wood = 1,
/obj/item/stack/material/fiber = 3
list(/obj/item/weapon/material/knife/stone = 1),
list(/obj/item/stack/material/flint = 1),
list(/obj/item/stack/material/wood = 1),
list(/obj/item/stack/material/fiber = 3)
)
time = 120
category = CAT_WEAPONRY
@@ -38,10 +38,10 @@
name = "stone knife"
result = /obj/item/weapon/material/knife/stone/bone
reqs = list(
/obj/item/weapon/material/knife/stone = 1,
/obj/item/stack/material/flint = 1,
/obj/item/weapon/bone = 1,
/obj/item/stack/material/fiber = 3
list(/obj/item/weapon/material/knife/stone = 1),
list(/obj/item/stack/material/flint = 1),
list(/obj/item/weapon/bone = 1),
list(/obj/item/stack/material/fiber = 3)
)
time = 120
category = CAT_WEAPONRY
@@ -51,9 +51,9 @@
name = "wooden bucket"
result = /obj/item/weapon/reagent_containers/glass/bucket/wood
reqs = list(
/obj/item/stack/material/wood = 1,
/obj/item/stack/material/stick = 1,
/obj/item/stack/material/fiber = 2
list(/obj/item/stack/material/wood = 1),
list(/obj/item/stack/material/stick = 1),
list(/obj/item/stack/material/fiber = 2)
)
time = 60
category = CAT_TOOL
@@ -61,7 +61,7 @@
/datum/crafting_recipe/sticks
name = "sticks"
result = /obj/item/stack/material/stick/fivestack
reqs = list(/obj/item/stack/material/wood = 1)
reqs = list(list(/obj/item/stack/material/wood = 1))
tool_paths = list(/obj/item/weapon/material/knife)
time = 200
category = CAT_MISC
@@ -70,10 +70,10 @@
name = "stone axe"
result = /obj/item/weapon/material/knife/machete/hatchet/stone
reqs = list(
/obj/item/weapon/material/knife/stone = 1,
/obj/item/stack/material/flint = 1,
/obj/item/stack/material/stick = 10,
/obj/item/stack/material/fiber = 3
list(/obj/item/weapon/material/knife/stone = 1),
list(/obj/item/stack/material/flint = 1),
list(/obj/item/stack/material/stick = 1),
list(/obj/item/stack/material/fiber = 3)
)
time = 120
category = CAT_WEAPONRY
@@ -83,10 +83,10 @@
name = "stone axe"
result = /obj/item/weapon/material/knife/machete/hatchet/stone/bone
reqs = list(
/obj/item/weapon/material/knife/stone = 1,
/obj/item/stack/material/flint = 1,
/obj/item/weapon/bone = 1,
/obj/item/stack/material/fiber = 3
list(/obj/item/weapon/material/knife/stone = 1),
list(/obj/item/stack/material/flint = 1),
list(/obj/item/weapon/bone = 1),
list(/obj/item/stack/material/fiber = 3)
)
time = 120
category = CAT_WEAPONRY
@@ -96,10 +96,10 @@
name = "stone spear"
result = /obj/item/weapon/material/twohanded/spear/flint
reqs = list(
/obj/item/weapon/material/knife/stone = 1,
/obj/item/stack/material/flint = 1,
/obj/item/stack/material/wood = 2,
/obj/item/stack/material/fiber = 3
list(/obj/item/weapon/material/knife/stone = 1),
list(/obj/item/stack/material/flint = 1),
list(/obj/item/stack/material/wood = 2),
list(/obj/item/stack/material/fiber = 3)
)
time = 120
category = CAT_WEAPONRY
@@ -109,10 +109,10 @@
name = "stone spear"
result = /obj/item/weapon/material/twohanded/spear/flint
reqs = list(
/obj/item/weapon/material/knife/stone = 1,
/obj/item/stack/material/flint = 1,
/obj/item/weapon/bone = 2,
/obj/item/stack/material/fiber = 3
list(/obj/item/weapon/material/knife/stone = 1),
list(/obj/item/stack/material/flint = 1),
list(/obj/item/weapon/bone = 2),
list(/obj/item/stack/material/fiber = 3)
)
time = 120
category = CAT_WEAPONRY
@@ -121,6 +121,6 @@
/datum/crafting_recipe/ropebindings
name = "rope bindings"
result = /obj/item/weapon/handcuffs/cable/plantfiber
reqs = list(/obj/item/stack/material/fiber = 3)
reqs = list(list(/obj/item/stack/material/fiber = 3))
time = 60
category = CAT_MISC

View File

@@ -1,9 +1,23 @@
/datum/crafting_recipe/stunprod
name = "Stunprod"
result = /obj/item/weapon/melee/baton/cattleprod
reqs = list(/obj/item/weapon/handcuffs/cable = 1,
/obj/item/stack/rods = 1,
/obj/item/weapon/tool/wirecutters = 1)
reqs = list(list(/obj/item/weapon/handcuffs/cable = 1),
list(/obj/item/stack/rods = 1),
list(/obj/item/weapon/tool/wirecutters = 1))
time = 40
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
/datum/crafting_recipe/spear
name = "Spear"
result = /obj/item/weapon/material/twohanded/spear
reqs = list(list(/obj/item/weapon/handcuffs/cable = 1),
list(/obj/item/stack/rods = 1),
list(/obj/item/weapon/material/shard = 1,
/obj/item/weapon/material/butterflyblade = 1)
)
parts = list(/obj/item/weapon/material/shard = 1,
/obj/item/weapon/material/butterflyblade = 1)
time = 40
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
@@ -11,10 +25,8 @@
/datum/crafting_recipe/shortbow
name = "Shortbow"
result = /obj/item/weapon/gun/launcher/crossbow/bow
reqs = list(
/obj/item/stack/material/wood = 10,
/obj/item/stack/material/cloth = 5
)
reqs = list(list(/obj/item/stack/material/wood = 10),
list(/obj/item/stack/material/cloth = 5))
time = 120
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
@@ -22,10 +34,8 @@
/datum/crafting_recipe/arrow_sandstone
name = "Wood arrow (sandstone tip)"
result = /obj/item/weapon/arrow/standard
reqs = list(
/obj/item/stack/material/wood = 2,
/obj/item/stack/material/sandstone = 2
)
reqs = list(list(/obj/item/stack/material/wood = 2),
list(/obj/item/stack/material/sandstone = 2))
time = 40
category = CAT_WEAPONRY
subcategory = CAT_AMMO
@@ -33,10 +43,8 @@
/datum/crafting_recipe/arrow_marble
name = "Wood arrow (marble tip)"
result = /obj/item/weapon/arrow/standard
reqs = list(
/obj/item/stack/material/wood = 2,
/obj/item/stack/material/marble = 2
)
reqs = list(list(/obj/item/stack/material/wood = 2),
list(/obj/item/stack/material/marble = 2))
time = 40
category = CAT_WEAPONRY
subcategory = CAT_AMMO