Personal Crafting - Initial Commit

This commit is contained in:
SamCroswell
2016-07-15 16:25:37 -04:00
parent 324e4b92a9
commit 0466499f86
33 changed files with 507 additions and 302 deletions
+1 -1
View File
@@ -184,7 +184,7 @@
desc = "Looks sneaky."
icon_state = "sheet-cloth"
/datum/table_recipe/shoe_rags
/datum/crafting_recipe/shoe_rags
name = "Shoe Rags"
result = /obj/item/shoe_silencer
+341
View File
@@ -0,0 +1,341 @@
/datum/personal_crafting
var/busy
var/viewing_category = 1 //typical powergamer starting on the Weapons tab
var/list/categories = list(CAT_WEAPON,CAT_AMMO,CAT_ROBOT,CAT_FOOD,CAT_MISC,CAT_PRIMAL)
//var/datum/action/innate/crafting/button // Holdover from when crafting was still an action button. TODO: Remove this before I commit.
/* This is what procs do:
get_environment - gets a list of things accessable for crafting by user
get_surroundings - takes a list of things and makes a list of key-types to values-amounts of said type in the list
check_contents - takes a recipe and a key-type list and checks if said recipe can be done with available stuff
check_tools - takes recipe, a key-type list, and a user and checks if there are enough tools to do the stuff, checks bugs one level deep
construct_item - takes a recipe and a user, call all the checking procs, calls do_after, checks all the things again, calls del_reqs, creates result, calls CheckParts of said result with argument being list returned by deel_reqs
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
*/
/datum/personal_crafting/proc/check_contents(datum/crafting_recipe/R, list/contents)
main_loop:
for(var/A in R.reqs)
var/needed_amount = R.reqs[A]
for(var/B in contents)
if(ispath(B, A))
if(contents[B] >= R.reqs[A])
continue main_loop
else
needed_amount -= contents[B]
if(needed_amount <= 0)
continue main_loop
else
continue
return 0
for(var/A in R.chem_catalists)
if(contents[A] < R.chem_catalists[A])
return 0
return 1
/datum/personal_crafting/proc/get_environment(mob/user)
. = list()
. += user.r_hand
. += user.l_hand
if(!istype(user.loc, /turf))
return
var/list/L = block(get_step(user, SOUTHWEST), get_step(user, NORTHEAST))
for(var/A in L)
var/turf/T = A
if(T.Adjacent(user))
. += T.contents
/datum/personal_crafting/proc/get_surroundings(mob/user)
. = list()
for(var/obj/item/I in get_environment(user))
if(istype(I, /obj/item/stack))
var/obj/item/stack/S = I
.[I.type] += S.amount
else
if(istype(I, /obj/item/weapon/reagent_containers))
var/obj/item/weapon/reagent_containers/RC = I
if(RC.flags & OPENCONTAINER)
for(var/datum/reagent/A in RC.reagents.reagent_list)
.[A.type] += A.volume
.[I.type] += 1
/datum/personal_crafting/proc/check_tools(mob/user, datum/crafting_recipe/R, list/contents)
if(!R.tools.len)
return 1
var/list/possible_tools = list()
for(var/obj/item/I in user.contents)
if(istype(I, /obj/item/weapon/storage))
for(var/obj/item/SI in I.contents)
possible_tools += SI.type
possible_tools += I.type
possible_tools += contents
main_loop:
for(var/A in R.tools)
for(var/I in possible_tools)
if(ispath(I,A))
continue main_loop
return 0
return 1
/datum/personal_crafting/proc/construct_item(mob/user, datum/crafting_recipe/R)
for(var/A in R.parts)
var/list/contents = get_surroundings(user)
var/send_feedback = 1
if(check_contents(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))
return ", missing component."
if(!check_tools(user, R, contents))
return ", missing tool."
var/list/parts = del_reqs(R, user)
var/atom/movable/I = new R.result (get_turf(user.loc))
I.CheckParts(parts, R)
if(send_feedback)
feedback_add_details("object_crafted","[I.type]")
return 0
return "."
return ", missing tool."
return ", missing component."
/*Del reqs works like this:
Loop over reqs var of the recipe
Set var amt to the value current cycle req is pointing to, its amount of type we need to delete
Get var/surroundings list of things accessable to crafting by get_environment()
Check the type of the current cycle req
If its reagent then do a while loop, inside it try to locate() reagent containers, inside such containers try to locate needed reagent, if there isnt remove thing from surroundings
If there is enough reagent in the search result then delete the needed amount, create the same type of reagent with the same data var and put it into deletion list
If there isnt enough take all of that reagent from the container, put into deletion list, substract the amt var by the volume of reagent, remove the container from surroundings list and keep searching
While doing above stuff check deletion list if it already has such reagnet, if yes merge instead of adding second one
If its stack check if it has enough amount
If yes create new stack with the needed amount and put in into deletion list, substract taken amount from the stack
If no put all of the stack in the deletion list, substract its amount from amt and keep searching
While doing above stuff check deletion list if it already has such stack type, if yes try to merge them instead of adding new one
If its anything else just locate() in in the list in a while loop, each find --s the amt var and puts the found stuff in deletion loop
Then do a loop over parts var of the recipe
Do similar stuff to what we have done above, but now in deletion list, until the parts conditions are satisfied keep taking from the deletion list and putting it into parts list for return
After its done loop over deletion list and delete all the shit that wasnt taken by parts loop
del_reqs return the list of parts resulting object will recieve as argument of CheckParts proc, on the atom level it will add them all to the contents, on all other levels it calls ..() and does whatever is needed afterwards but from contents list already
*/
/datum/personal_crafting/proc/del_reqs(datum/crafting_recipe/R, mob/user)
var/list/surroundings
var/list/Deletion = list()
. = list()
var/data
var/amt
main_loop:
for(var/A in R.reqs)
amt = R.reqs[A]
surroundings = get_environment(user)
surroundings -= Deletion
if(ispath(A, /datum/reagent))
var/datum/reagent/RG = new A
var/datum/reagent/RGNT
while(amt > 0)
var/obj/item/weapon/reagent_containers/RC = locate() in surroundings
RG = RC.reagents.get_reagent(A)
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)
else
surroundings -= RC
else if(ispath(A, /obj/item/stack))
var/obj/item/stack/S
var/obj/item/stack/SD
while(amt > 0)
S = locate(A) in surroundings
if(S.amount >= amt)
if(!locate(S.type) in Deletion)
SD = new S.type()
Deletion += SD
S.use(amt)
SD = locate(S.type) in Deletion
SD.amount += amt
continue main_loop
else
amt -= S.amount
if(!locate(S.type) in Deletion)
Deletion += S
else
data = S.amount
S = locate(S.type) in Deletion
S.amount += data
surroundings -= S
else
var/atom/movable/I
while(amt > 0)
I = locate(A) 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/A in R.parts)
if(istype(A, /datum/reagent))
var/datum/reagent/RG = locate(A) in Deletion
if(RG.volume > partlist[A])
RG.volume = partlist[A]
. += RG
Deletion -= RG
continue
else if(istype(A, /obj/item/stack))
var/obj/item/stack/ST = locate(A) in Deletion
if(ST.amount > partlist[A])
ST.amount = partlist[A]
. += ST
Deletion -= ST
continue
else
while(partlist[A] > 0)
var/atom/movable/AM = locate(A) in Deletion
. += AM
Deletion -= AM
partlist[A] -= 1
while(Deletion.len)
var/DL = Deletion[Deletion.len]
Deletion.Cut(Deletion.len)
qdel(DL)
/datum/personal_crafting/proc/craft(mob/user)
if(user.incapacitated() || user.lying || istype(user.loc, /obj/mecha))
return
var/list/surroundings = get_surroundings(user)
var/dat = "<h3>Crafting menu</h3>"
if(busy)
dat += "<div class='statusDisplay'>"
dat += "Crafting in progress...</div>"
else
dat += "<A href='?src=\ref[src];backwardCat=1'><--</A>"
dat += " [categories[prev_cat()]] |"
dat += " <B>[categories[viewing_category]]</B> "
dat += "| [categories[next_cat()]] "
dat += "<A href='?src=\ref[src];forwardCat=1'>--></A><BR><BR>"
dat += "<div class='statusDisplay'>"
//Filter the recipes we can craft to the top
var/list/can_craft = list()
var/list/cant_craft = list()
for(var/datum/crafting_recipe/R in crafting_recipes)
if(R.category != categories[viewing_category])
continue
if(check_contents(R, surroundings))
can_craft += R
else
cant_craft += R
for(var/datum/crafting_recipe/R in can_craft)
dat += build_recipe_text(R, surroundings)
for(var/datum/crafting_recipe/R in cant_craft)
dat += build_recipe_text(R, surroundings)
dat += "</div>"
var/datum/browser/popup = new(user, "crafting", "Crafting", 500, 500)
popup.set_content(dat)
popup.open()
return
/datum/personal_crafting/Topic(href, href_list)
if(usr.stat || usr.lying)
return
if(href_list["make"])
var/datum/crafting_recipe/TR = locate(href_list["make"])
busy = 1
craft(usr)
var/fail_msg = construct_item(usr, TR)
if(!fail_msg)
usr << "<span class='notice'>[TR.name] constructed.</span>"
else
usr << "<span class ='warning'>Construction failed[fail_msg]</span>"
busy = 0
craft(usr)
if(href_list["forwardCat"])
viewing_category = next_cat()
usr << "<span class='notice'>Category is now [categories[viewing_category]].</span>"
craft(usr)
if(href_list["backwardCat"])
viewing_category = prev_cat()
usr << "<span class='notice'>Category is now [categories[viewing_category]].</span>"
craft(usr)
//Next works nicely with modular arithmetic
/datum/personal_crafting/proc/next_cat()
. = viewing_category % categories.len + 1
//Previous can go fuck itself
/datum/personal_crafting/proc/prev_cat()
if(viewing_category == categories.len)
. = viewing_category-1
else
. = viewing_category % categories.len - 1
if(. <= 0)
. = categories.len
/datum/personal_crafting/proc/build_recipe_text(datum/crafting_recipe/R, list/contents)
. = ""
var/name_text = ""
var/req_text = ""
var/tool_text = ""
var/catalist_text = ""
if(check_contents(R, contents))
name_text ="<A href='?src=\ref[src];make=\ref[R]'>[R.name]</A>"
else
name_text = "<span class='linkOff'>[R.name]</span>"
if(name_text)
for(var/A in R.reqs)
if(ispath(A, /obj))
var/obj/O = A
req_text += " [R.reqs[A]] [initial(O.name)]"
else if(ispath(A, /datum/reagent))
var/datum/reagent/RE = A
req_text += " [R.reqs[A]] [initial(RE.name)]"
if(R.chem_catalists.len)
catalist_text += ", Catalysts:"
for(var/C in R.chem_catalists)
if(ispath(C, /datum/reagent))
var/datum/reagent/RE = C
catalist_text += " [R.chem_catalists[C]] [initial(RE.name)]"
if(R.tools.len)
tool_text += ", Tools:"
for(var/O in R.tools)
if(ispath(O, /obj))
var/obj/T = O
tool_text += " [R.tools[O]] [initial(T.name)]"
. = "[name_text][req_text][tool_text][catalist_text]<BR>"
+47 -26
View File
@@ -1,4 +1,4 @@
/datum/table_recipe
/datum/crafting_recipe
var/name = "" //in-game display name
var/reqs[] = list() //type paths of items consumed associated with how many are needed
var/result //type path of item resulting from this craft
@@ -7,14 +7,15 @@
var/parts[] = list() //type paths of items that will be placed in the result
var/chem_catalists[] = list() //like tools but for reagents
var/fruit[] = list() //grown products required by the recipe
var/category = CAT_MISC // Recipe category
/datum/table_recipe/proc/AdjustChems(var/obj/resultobj as obj)
/datum/crafting_recipe/proc/AdjustChems(var/obj/resultobj as obj)
//This proc is to replace the make_food proc of recipes from microwaves and such that are being converted to table crafting recipes.
//Use it to handle the removal of reagents after the food has been created (like removing toxins from a salad made with ambrosia)
//If a recipe does not require it's chems adjusted, don't bother declaring this for the recipe, as it will call this placeholder
return
/datum/table_recipe/IED
/datum/crafting_recipe/IED
name = "IED"
result = /obj/item/weapon/grenade/iedcasing/filled
reqs = list(/datum/reagent/fuel = 50,
@@ -23,8 +24,9 @@
/obj/item/weapon/reagent_containers/food/drinks/cans = 1)
parts = list(/obj/item/weapon/reagent_containers/food/drinks/cans = 1)
time = 80
category = CAT_WEAPON
/datum/table_recipe/stunprod
/datum/crafting_recipe/stunprod
name = "Stunprod"
result = /obj/item/weapon/melee/baton/cattleprod
reqs = list(/obj/item/weapon/restraints/handcuffs/cable = 1,
@@ -33,8 +35,9 @@
/obj/item/weapon/stock_parts/cell = 1)
time = 80
parts = list(/obj/item/weapon/stock_parts/cell = 1)
category = CAT_WEAPON
/datum/table_recipe/ed209
/datum/crafting_recipe/ed209
name = "ED209"
result = /mob/living/simple_animal/bot/ed209
reqs = list(/obj/item/robot_parts/robot_suit = 1,
@@ -50,8 +53,9 @@
/obj/item/robot_parts/r_arm = 1)
tools = list(/obj/item/weapon/weldingtool, /obj/item/weapon/screwdriver)
time = 120
category = CAT_ROBOT
/datum/table_recipe/secbot
/datum/crafting_recipe/secbot
name = "Secbot"
result = /mob/living/simple_animal/bot/secbot
reqs = list(/obj/item/device/assembly/signaler = 1,
@@ -61,16 +65,18 @@
/obj/item/robot_parts/r_arm = 1)
tools = list(/obj/item/weapon/weldingtool)
time = 120
category = CAT_ROBOT
/datum/table_recipe/cleanbot
/datum/crafting_recipe/cleanbot
name = "Cleanbot"
result = /mob/living/simple_animal/bot/cleanbot
reqs = list(/obj/item/weapon/reagent_containers/glass/bucket = 1,
/obj/item/device/assembly/prox_sensor = 1,
/obj/item/robot_parts/r_arm = 1)
time = 80
category = CAT_ROBOT
/datum/table_recipe/floorbot
/datum/crafting_recipe/floorbot
name = "Floorbot"
result = /mob/living/simple_animal/bot/floorbot
reqs = list(/obj/item/weapon/storage/toolbox/mechanical = 1,
@@ -78,8 +84,9 @@
/obj/item/device/assembly/prox_sensor = 1,
/obj/item/robot_parts/r_arm = 1)
time = 80
category = CAT_ROBOT
/datum/table_recipe/medbot
/datum/crafting_recipe/medbot
name = "Medbot"
result = /mob/living/simple_animal/bot/medbot
reqs = list(/obj/item/device/healthanalyzer = 1,
@@ -87,8 +94,9 @@
/obj/item/device/assembly/prox_sensor = 1,
/obj/item/robot_parts/r_arm = 1)
time = 80
category = CAT_ROBOT
/datum/table_recipe/flamethrower
/datum/crafting_recipe/flamethrower
name = "Flamethrower"
result = /obj/item/weapon/flamethrower
reqs = list(/obj/item/weapon/weldingtool = 1,
@@ -96,8 +104,9 @@
/obj/item/stack/rods = 2)
tools = list(/obj/item/weapon/screwdriver)
time = 20
category = CAT_WEAPON
/datum/table_recipe/meteorshot
/datum/crafting_recipe/meteorshot
name = "Meteorshot Shell"
result = /obj/item/ammo_casing/shotgun/meteorshot
reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
@@ -105,8 +114,9 @@
/obj/item/weapon/stock_parts/manipulator = 2)
tools = list(/obj/item/weapon/screwdriver)
time = 5
category = CAT_AMMO
/datum/table_recipe/pulseslug
/datum/crafting_recipe/pulseslug
name = "Pulse Slug Shell"
result = /obj/item/ammo_casing/shotgun/pulseslug
reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
@@ -114,16 +124,18 @@
/obj/item/weapon/stock_parts/micro_laser/ultra = 1)
tools = list(/obj/item/weapon/screwdriver)
time = 5
category = CAT_AMMO
/datum/table_recipe/dragonsbreath
/datum/crafting_recipe/dragonsbreath
name = "Dragonsbreath Shell"
result = /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath
reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
/datum/reagent/phosphorus = 5,)
tools = list(/obj/item/weapon/screwdriver)
time = 5
category = CAT_AMMO
/datum/table_recipe/frag12
/datum/crafting_recipe/frag12
name = "FRAG-12 Shell"
result = /obj/item/ammo_casing/shotgun/frag12
reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
@@ -132,8 +144,9 @@
/datum/reagent/facid = 5,)
tools = list(/obj/item/weapon/screwdriver)
time = 5
category = CAT_AMMO
/datum/table_recipe/ionslug
/datum/crafting_recipe/ionslug
name = "Ion Scatter Shell"
result = /obj/item/ammo_casing/shotgun/ion
reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
@@ -141,8 +154,9 @@
/obj/item/weapon/stock_parts/subspace/crystal = 1)
tools = list(/obj/item/weapon/screwdriver)
time = 5
category = CAT_AMMO
/datum/table_recipe/improvisedslug
/datum/crafting_recipe/improvisedslug
name = "Improvised Shotgun Shell"
result = /obj/item/ammo_casing/shotgun/improvised
reqs = list(/obj/item/weapon/grenade/chem_grenade = 1,
@@ -151,16 +165,18 @@
/datum/reagent/fuel = 10)
tools = list(/obj/item/weapon/screwdriver)
time = 5
category = CAT_AMMO
/datum/table_recipe/improvisedslugoverload
/datum/crafting_recipe/improvisedslugoverload
name = "Overload Improvised Shell"
result = /obj/item/ammo_casing/shotgun/improvised/overload
reqs = list(/obj/item/ammo_casing/shotgun/improvised = 1,
/datum/reagent/blackpowder = 5)
tools = list(/obj/item/weapon/screwdriver)
time = 5
category = CAT_AMMO
/datum/table_recipe/laserslug
/datum/crafting_recipe/laserslug
name = "Laser Slug Shell"
result = /obj/item/ammo_casing/shotgun/laserslug
reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
@@ -168,8 +184,9 @@
/obj/item/weapon/stock_parts/micro_laser/high = 1)
tools = list(/obj/item/weapon/screwdriver)
time = 5
category = CAT_AMMO
/datum/table_recipe/ishotgun
/datum/crafting_recipe/ishotgun
name = "Improvised Shotgun"
result = /obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised
reqs = list(/obj/item/weaponcrafting/receiver = 1,
@@ -178,8 +195,9 @@
/obj/item/stack/packageWrap = 5,)
tools = list(/obj/item/weapon/screwdriver)
time = 200
category = CAT_WEAPON
/datum/table_recipe/spooky_camera
/datum/crafting_recipe/spooky_camera
name = "Camera Obscura"
result = /obj/item/device/camera/spooky
time = 15
@@ -187,29 +205,31 @@
/datum/reagent/holywater = 10)
parts = list(/obj/item/device/camera = 1)
/datum/table_recipe/notreallysoap
/datum/crafting_recipe/notreallysoap
name = "Homemade Soap"
result = /obj/item/weapon/soap/ducttape
time = 100
reqs = list(/obj/item/stack/tape_roll = 1,
/datum/reagent/liquidgibs = 10)
/datum/table_recipe/garrote
/datum/crafting_recipe/garrote
name = "Makeshift Garrote"
result = /obj/item/weapon/twohanded/garrote/improvised
time = 15
reqs = list(/obj/item/stack/sheet/wood = 1,
/obj/item/stack/cable_coil = 5)
tools = list(/obj/item/weapon/kitchen/knife) // Gotta carve the wood into handles
category = CAT_WEAPON
/datum/table_recipe/makeshift_bolt
/datum/crafting_recipe/makeshift_bolt
name = "Makeshift Bolt"
result = /obj/item/weapon/arrow/rod
time = 15
reqs = list(/obj/item/stack/rods = 1)
tools = list(/obj/item/weapon/weldingtool)
category = CAT_AMMO
/datum/table_recipe/crossbow
/datum/crafting_recipe/crossbow
name = "Powered Crossbow"
result = /obj/item/weapon/gun/throw/crossbow
time = 300
@@ -219,10 +239,11 @@
/obj/item/stack/sheet/wood = 5)
tools = list(/obj/item/weapon/weldingtool,
/obj/item/weapon/screwdriver)
category = CAT_WEAPON
/datum/table_recipe/glove_balloon
/datum/crafting_recipe/glove_balloon
name = "Latex Glove Balloon"
result = /obj/item/latexballon
time = 15
reqs = list(/obj/item/clothing/gloves/color/latex = 1,
/obj/item/stack/cable_coil = 5)
/obj/item/stack/cable_coil = 5)
-225
View File
@@ -1,225 +0,0 @@
#define TABLECRAFT_MAX_ITEMS 30
/obj/structure/table
var/list/table_contents = list()
/obj/structure/table/MouseDrop(atom/over)
if(over != usr)
return
interact(usr)
/obj/structure/table/proc/check_contents(datum/table_recipe/R)
check_table()
main_loop:
if(R.fruit)
for(var/A in R.fruit)
for(var/B in table_contents)
if(B == A)
if(table_contents[B] >= R.fruit[A])
continue main_loop
return 0
for(var/A in R.reqs)
for(var/B in table_contents)
if(ispath(B, A))
if(table_contents[B] >= R.reqs[A])
continue main_loop
return 0
for(var/A in R.chem_catalists)
if(table_contents[A] < R.chem_catalists[A])
return 0
return 1
/obj/structure/table/proc/check_table()
table_contents = list()
for(var/obj/item/I in loc)
if(istype(I, /obj/item/stack))
var/obj/item/stack/S = I
table_contents[I.type] += S.amount
else if(istype(I, /obj/item/weapon/reagent_containers/food/snacks/grown))
var/obj/item/weapon/reagent_containers/food/snacks/grown/G = I
if(G.seed && G.seed.kitchen_tag)
table_contents[G.seed.kitchen_tag] += 1
else
if(istype(I, /obj/item/weapon/reagent_containers))
var/obj/item/weapon/reagent_containers/RC = I
if(RC.flags & OPENCONTAINER)
for(var/datum/reagent/A in RC.reagents.reagent_list)
table_contents[A.type] += A.volume
table_contents[I.type] += 1
/obj/structure/table/proc/check_tools(mob/user, datum/table_recipe/R)
if(!R.tools.len)
return 1
var/list/possible_tools = list()
for(var/obj/item/I in user.contents)
if(istype(I, /obj/item/weapon/storage))
for(var/obj/item/SI in I.contents)
possible_tools += SI.type
else
possible_tools += I.type
possible_tools += table_contents
var/i = R.tools.len
var/I
for(var/A in R.tools)
I = possible_tools.Find(A)
if(I)
possible_tools.Cut(I, I+1)
i--
else
break
return !i
/obj/structure/table/proc/construct_item(mob/user, datum/table_recipe/R)
check_table()
if(check_contents(R) && check_tools(user, R))
if(do_after(user, R.time, target = src))
if(!check_contents(R) || !check_tools(user, R))
return 0
var/atom/movable/I = new R.result (loc)
var/list/parts = del_reqs(R, I)
for(var/A in parts)
if(istype(A, /obj/item))
var/atom/movable/B = A
B.loc = I
else
if(!I.reagents)
I.reagents = new /datum/reagents()
I.reagents.reagent_list.Add(A)
I.CheckParts()
R.AdjustChems(I)
return 1
return 0
/obj/structure/table/proc/del_reqs(datum/table_recipe/R, atom/movable/resultobject)
var/list/Deletion = list()
var/amt
var/reagenttransfer = 0
if(istype(resultobject,/obj/item/weapon/reagent_containers))
reagenttransfer = 1
if(R.fruit)
for(var/A in R.fruit)
amt = R.fruit[A]
fruit_loop: //ha
for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in loc)
if(G.seed && G.seed.kitchen_tag && (G.seed.kitchen_tag == A))
amt--
G.loc = null //remove it from the table loc so that we don't locate the same fruit every time
if(reagenttransfer)
G.reagents.trans_to(resultobject, G.reagents.total_volume)
qdel(G)
if(amt <= 0)
break fruit_loop
for(var/A in R.reqs)
amt = R.reqs[A]
if(ispath(A, /obj/item/stack))
var/obj/item/stack/S
stack_loop:
for(var/B in table_contents)
if(ispath(B, A))
while(amt > 0)
S = locate(B) in loc
if(S.amount >= amt)
S.use(amt)
break stack_loop
else
amt -= S.amount
qdel(S)
else if(ispath(A, /obj/item))
var/obj/item/I
item_loop:
for(var/B in table_contents)
if(ispath(B, A))
while(amt > 0)
I = locate(B) in loc
Deletion.Add(I)
I.loc = null //remove it from the table loc so that we don't locate the same item every time (will be relocated inside the crafted item in construct_item())
amt--
if(reagenttransfer && istype(I,/obj/item/weapon/reagent_containers))
var/obj/item/weapon/reagent_containers/RC = I
RC.reagents.trans_to(resultobject, RC.reagents.total_volume)
break item_loop
else
var/datum/reagent/RG = new A
reagent_loop:
for(var/B in table_contents)
if(ispath(B, /obj/item/weapon/reagent_containers))
var/obj/item/RC = locate(B) in loc
if(RC.reagents.has_reagent(RG.id, amt))
if(reagenttransfer)
RC.reagents.trans_id_to(resultobject,RG.id, amt)
else
RC.reagents.remove_reagent(RG.id, amt)
RG.volume = amt
Deletion.Add(RG)
break reagent_loop
else if(RC.reagents.has_reagent(RG.id))
Deletion.Add(RG)
RG.volume += RC.reagents.get_reagent_amount(RG.id)
amt -= RC.reagents.get_reagent_amount(RG.id)
if(reagenttransfer)
RC.reagents.trans_id_to(resultobject,RG.id, RG.volume)
else
RC.reagents.del_reagent(RG.id)
var/list/partlist = list(R.parts.len)
for(var/M in R.parts)
partlist[M] = R.parts[M]
deletion_loop:
for(var/B in Deletion)
for(var/A in R.parts)
if(istype(B, A))
if(partlist[A] > 0) //do we still need a part like that?
partlist[A] -= 1
continue deletion_loop
Deletion.Remove(B)
qdel(B)
return Deletion
/obj/structure/table/interact(mob/user)
if(user.stat || user.lying || !Adjacent(user))
return
check_table()
if(!table_contents.len)
return
user.face_atom(src)
var/dat = "<h3>Crafting menu</h3>"
dat += "<div class='statusDisplay'>"
if(busy)
dat += "Crafting in progress...</div>"
else
for(var/datum/table_recipe/R in table_recipes)
if(check_contents(R))
dat += "<A href='?src=\ref[src];make=\ref[R]'>[R.name]</A><BR>"
dat += "</div>"
var/datum/browser/popup = new(user, "table", "Table", 300, 300)
popup.set_content(dat)
popup.open()
return
/obj/structure/table/Topic(href, href_list)
if(usr.stat || !Adjacent(usr) || usr.lying)
return
if(href_list["make"])
if(!check_table_space())
to_chat(usr, "<span class ='warning'>The table is too crowded.</span>")
return
var/datum/table_recipe/TR = locate(href_list["make"])
busy = 1
interact(usr)
if(construct_item(usr, TR))
to_chat(usr, "<span class='notice'>[TR.name] constructed.</span>")
else
to_chat(usr, "<span class ='warning'>Construction failed.</span>")
busy = 0
interact(usr)
/obj/structure/table/proc/check_table_space()
var/Item_amount = 0
for(var/obj/item/I in loc)
Item_amount++
if(Item_amount <= TABLECRAFT_MAX_ITEMS) //is the table crowded?
return 1
#undef TABLECRAFT_MAX_ITEMS
+48 -30
View File
@@ -1,5 +1,5 @@
/* Example for reference when defining recipes
/datum/table_recipe/food
/datum/crafting_recipe/food
name = "" //in-game display name
reqs[] = list() //type paths of items/reagents consumed associated with how many are needed (equivalent to var/list/items and var/list/reagents combined)
result //type path of item resulting from this craft
@@ -9,7 +9,7 @@
fruit[] = list() //grown products required by the recipe
*/
/datum/table_recipe/sandwich
/datum/crafting_recipe/sandwich
name = "Sandwich"
reqs = list(
/obj/item/weapon/reagent_containers/food/snacks/meatsteak = 1,
@@ -17,55 +17,61 @@
/obj/item/weapon/reagent_containers/food/snacks/cheesewedge = 1,
)
result = /obj/item/weapon/reagent_containers/food/snacks/sandwich
category = CAT_FOOD
/datum/table_recipe/slimesandwich
/datum/crafting_recipe/slimesandwich
name = "Slime Jelly Sandwich"
reqs = list(
/datum/reagent/slimejelly = 5,
/obj/item/weapon/reagent_containers/food/snacks/breadslice = 2,
)
result = /obj/item/weapon/reagent_containers/food/snacks/jellysandwich/slime
category = CAT_FOOD
/datum/table_recipe/cherrysandwich
/datum/crafting_recipe/cherrysandwich
name = "Cherry Jelly Sandwich"
reqs = list(
/datum/reagent/cherryjelly = 5,
/obj/item/weapon/reagent_containers/food/snacks/breadslice = 2,
)
result = /obj/item/weapon/reagent_containers/food/snacks/jellysandwich/cherry
category = CAT_FOOD
/datum/table_recipe/slimeburger
/datum/crafting_recipe/slimeburger
name = "Slime Jelly Burger"
reqs = list(
/datum/reagent/slimejelly = 5,
/obj/item/weapon/reagent_containers/food/snacks/bun = 1,
)
result = /obj/item/weapon/reagent_containers/food/snacks/jellyburger/slime
category = CAT_FOOD
/datum/table_recipe/jellyburger
/datum/crafting_recipe/jellyburger
name = "Cherry Jelly Burger"
reqs = list(
/datum/reagent/cherryjelly = 5,
/obj/item/weapon/reagent_containers/food/snacks/bun = 1,
)
result = /obj/item/weapon/reagent_containers/food/snacks/jellyburger/cherry
category = CAT_FOOD
/datum/table_recipe/herbsalad
/* Temporarily disabled until we can find a workaround for this fruit shit.
/datum/crafting_recipe/herbsalad
name = "herb salad"
fruit = list("ambrosia" = 3, "apple" = 1)
result = /obj/item/weapon/reagent_containers/food/snacks/herbsalad
/datum/table_recipe/herbsalad/AdjustChems(var/obj/resultobj as obj)
/datum/crafting_recipe/herbsalad/AdjustChems(var/obj/resultobj as obj)
if(istype(resultobj, /obj/item/weapon/reagent_containers))
var/obj/item/weapon/reagent_containers/RC = resultobj
RC.reagents.del_reagent("toxin")
/datum/table_recipe/aesirsalad
/datum/crafting_recipe/aesirsalad
name = "Aesir salad"
fruit = list("ambrosiadeus" = 3, "goldapple" = 1)
result = /obj/item/weapon/reagent_containers/food/snacks/aesirsalad
/datum/table_recipe/validsalad
/datum/crafting_recipe/validsalad
name = "valid salad"
fruit = list("ambrosia" = 3, "potato" = 1)
reqs = list(
@@ -73,20 +79,12 @@
)
result = /obj/item/weapon/reagent_containers/food/snacks/validsalad
/datum/table_recipe/validsalad/AdjustChems(var/obj/resultobj as obj)
/datum/crafting_recipe/validsalad/AdjustChems(var/obj/resultobj as obj)
if(istype(resultobj, /obj/item/weapon/reagent_containers))
var/obj/item/weapon/reagent_containers/RC = resultobj
RC.reagents.del_reagent("toxin")
/datum/table_recipe/notasandwich
name = "not-a-sandwich"
reqs = list(
/obj/item/weapon/reagent_containers/food/snacks/breadslice = 2,
/obj/item/clothing/mask/fakemoustache = 1,
)
result = /obj/item/weapon/reagent_containers/food/snacks/notasandwich
/datum/table_recipe/wrap
/datum/crafting_recipe/wrap
name = "egg wrap"
fruit = list("cabbage" = 1)
reqs = list(
@@ -94,75 +92,95 @@
/obj/item/weapon/reagent_containers/food/snacks/friedegg = 1,
)
result = /obj/item/weapon/reagent_containers/food/snacks/wrap
*/
/datum/table_recipe/sushi_Ebi
/datum/crafting_recipe/notasandwich
name = "not-a-sandwich"
reqs = list(
/obj/item/weapon/reagent_containers/food/snacks/breadslice = 2,
/obj/item/clothing/mask/fakemoustache = 1,
)
result = /obj/item/weapon/reagent_containers/food/snacks/notasandwich
category = CAT_FOOD
/datum/crafting_recipe/sushi_Ebi
name = "Ebi Sushi"
reqs = list(
/obj/item/weapon/reagent_containers/food/snacks/boiledrice = 1,
/obj/item/weapon/reagent_containers/food/snacks/boiled_shrimp = 1,
)
result = /obj/item/weapon/reagent_containers/food/snacks/sushi_Ebi
category = CAT_FOOD
/datum/table_recipe/sushi_Ikura
/datum/crafting_recipe/sushi_Ikura
name = "Ikura Sushi"
reqs = list(
/obj/item/weapon/reagent_containers/food/snacks/boiledrice = 1,
/obj/item/fish_eggs/salmon = 1,
)
result = /obj/item/weapon/reagent_containers/food/snacks/sushi_Ikura
category = CAT_FOOD
/datum/table_recipe/sushi_Inari
/datum/crafting_recipe/sushi_Inari
name = "Inari Sushi"
reqs = list(
/obj/item/weapon/reagent_containers/food/snacks/boiledrice = 1,
/obj/item/weapon/reagent_containers/food/snacks/fried_tofu = 1,
)
result = /obj/item/weapon/reagent_containers/food/snacks/sushi_Inari
category = CAT_FOOD
/datum/table_recipe/sushi_Sake
/datum/crafting_recipe/sushi_Sake
name = "Sake Sushi"
reqs = list(
/obj/item/weapon/reagent_containers/food/snacks/boiledrice = 1,
/obj/item/weapon/reagent_containers/food/snacks/salmonmeat = 1,
)
result = /obj/item/weapon/reagent_containers/food/snacks/sushi_Sake
category = CAT_FOOD
/datum/table_recipe/sushi_SmokedSalmon
/datum/crafting_recipe/sushi_SmokedSalmon
name = "Smoked Salmon Sushi"
reqs = list(
/obj/item/weapon/reagent_containers/food/snacks/boiledrice = 1,
/obj/item/weapon/reagent_containers/food/snacks/salmonsteak = 1,
)
result = /obj/item/weapon/reagent_containers/food/snacks/sushi_SmokedSalmon
category = CAT_FOOD
/datum/table_recipe/sushi_Masago
/datum/crafting_recipe/sushi_Masago
name = "Masago Sushi"
reqs = list(
/obj/item/weapon/reagent_containers/food/snacks/boiledrice = 1,
/obj/item/fish_eggs/goldfish = 1,
)
result = /obj/item/weapon/reagent_containers/food/snacks/sushi_Masago
category = CAT_FOOD
/datum/table_recipe/sushi_Tobiko
/datum/crafting_recipe/sushi_Tobiko
name = "Tobiko Sushi"
reqs = list(
/obj/item/weapon/reagent_containers/food/snacks/boiledrice = 1,
/obj/item/fish_eggs/shark = 1,
)
result = /obj/item/weapon/reagent_containers/food/snacks/sushi_Tobiko
category = CAT_FOOD
/datum/table_recipe/sushi_TobikoEgg
/datum/crafting_recipe/sushi_TobikoEgg
name = "Tobiko and Egg Sushi"
reqs = list(
/obj/item/weapon/reagent_containers/food/snacks/sushi_Tobiko = 1,
/obj/item/weapon/reagent_containers/food/snacks/egg = 1,
)
result = /obj/item/weapon/reagent_containers/food/snacks/sushi_TobikoEgg
category = CAT_FOOD
/datum/table_recipe/sushi_Tai
/datum/crafting_recipe/sushi_Tai
name = "Tai Sushi"
reqs = list(
/obj/item/weapon/reagent_containers/food/snacks/boiledrice = 1,
/obj/item/weapon/reagent_containers/food/snacks/catfishmeat = 1,
)
result = /obj/item/weapon/reagent_containers/food/snacks/sushi_Tai
result = /obj/item/weapon/reagent_containers/food/snacks/sushi_Tai
category = CAT_FOOD
@@ -39,6 +39,8 @@
martial_art = default_martial_art
handcrafting = new()
var/mob/M = src
faction |= "\ref[M]" //what
@@ -53,6 +55,9 @@
UpdateAppearance()
/mob/living/carbon/human/OpenCraftingMenu()
handcrafting.craft(src)
/mob/living/carbon/human/prepare_data_huds()
//Update med hud images...
..()
@@ -53,6 +53,8 @@ var/global/default_martial_art = new/datum/martial_art
var/speech_problem_flag = 0
var/datum/personal_crafting/handcrafting
var/datum/martial_art/martial_art = null
var/special_voice = "" // For changing our voice. Used by a symptom.
+3
View File
@@ -3,6 +3,9 @@
..()
return QDEL_HINT_HARDDEL_NOW
/mob/living/proc/OpenCraftingMenu()
return
/mob/living/Stat()
. = ..()
if(. && get_rig_stats)
+1
View File
@@ -154,6 +154,7 @@
/obj/item/device/camera/spooky/CheckParts()
..()
var/obj/item/device/camera/C = locate(/obj/item/device/camera) in contents
if(C)
pictures_max = C.pictures_max
-2
View File
@@ -301,8 +301,6 @@ var/global/list/obj/item/device/pda/PDAs = list()
to_chat(usr, "<span class='notice'>You cannot do this while restrained.</span>")
/obj/item/device/pda/AltClick()
..()
if(issilicon(usr))
return
+4 -1
View File
@@ -520,6 +520,9 @@ var/const/INGEST = 2
return res
/datum/reagents/proc/get_reagent(type)
. = locate(type) in reagent_list
/datum/reagents/proc/remove_all_type(var/reagent_type, var/amount, var/strict = 0, var/safety = 1) // Removes all reagent of X type. @strict set to 1 determines whether the childs of the type are included.
if(!isnum(amount)) return 1
@@ -608,4 +611,4 @@ atom/proc/create_reagents(var/max_vol)
reagent_list.Cut()
reagent_list = null
if(my_atom && my_atom.reagents == src)
my_atom.reagents = null
my_atom.reagents = null