mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-13 16:13:19 +01:00
Table crafting refactor
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
// This file is for projectile weapon crafting. All parts and construction paths will be contained here.
|
||||
// The weapons themselves are children of other weapons and should be contained in their respective files.
|
||||
|
||||
// PARTS //
|
||||
|
||||
/obj/item/weaponcrafting/receiver
|
||||
name = "modular receiver"
|
||||
desc = "A prototype modular receiver and trigger assembly for a firearm."
|
||||
icon = 'icons/obj/improvised.dmi'
|
||||
icon_state = "receiver"
|
||||
|
||||
/obj/item/weaponcrafting/stock
|
||||
name = "rifle stock"
|
||||
desc = "A classic rifle stock that doubles as a grip, roughly carved out of wood."
|
||||
icon = 'icons/obj/improvised.dmi'
|
||||
icon_state = "riflestock"
|
||||
|
||||
|
||||
// CRAFTING //
|
||||
|
||||
/obj/item/weaponcrafting/receiver/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/pipe))
|
||||
user << "You attach the shotgun barrel to the receiver. The pins seem loose."
|
||||
var/obj/item/weaponcrafting/ishotgunconstruction/I = new /obj/item/weaponcrafting/ishotgunconstruction
|
||||
user.unEquip(src)
|
||||
user.put_in_hands(I)
|
||||
del(W)
|
||||
del(src)
|
||||
return
|
||||
|
||||
// SHOTGUN //
|
||||
|
||||
/obj/item/weaponcrafting/ishotgunconstruction
|
||||
name = "slightly conspicuous metal construction"
|
||||
desc = "A long pipe attached to a firearm receiver. The pins seem loose."
|
||||
icon = 'icons/obj/improvised.dmi'
|
||||
icon_state = "ishotgunstep1"
|
||||
|
||||
/obj/item/weaponcrafting/ishotgunconstruction/attackby(var/obj/item/I, mob/user as mob)
|
||||
..()
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
var/obj/item/weaponcrafting/ishotgunconstruction2/C = new /obj/item/weaponcrafting/ishotgunconstruction2
|
||||
user.unEquip(src)
|
||||
user.put_in_hands(C)
|
||||
user << "<span class='notice'>You screw the pins into place, securing the pipe to the receiver.</span>"
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weaponcrafting/ishotgunconstruction2
|
||||
name = "very conspicuous metal construction"
|
||||
desc = "A long pipe attached to a trigger assembly."
|
||||
icon = 'icons/obj/improvised.dmi'
|
||||
icon_state = "ishotgunstep1"
|
||||
|
||||
/obj/item/weaponcrafting/ishotgunconstruction2/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/weaponcrafting/stock))
|
||||
user << "You attach the stock to the receiver-barrel assembly."
|
||||
var/obj/item/weaponcrafting/ishotgunconstruction3/I = new /obj/item/weaponcrafting/ishotgunconstruction3
|
||||
user.unEquip(src)
|
||||
user.put_in_hands(I)
|
||||
del(W)
|
||||
del(src)
|
||||
return
|
||||
|
||||
/obj/item/weaponcrafting/ishotgunconstruction3
|
||||
name = "extremely conspicuous metal construction"
|
||||
desc = "A receiver-barrel shotgun assembly with a loose wooden stock. There's no way you can fire it without the stock coming loose."
|
||||
icon = 'icons/obj/improvised.dmi'
|
||||
icon_state = "ishotgunstep2"
|
||||
|
||||
/obj/item/weaponcrafting/ishotgunconstruction3/attackby(var/obj/item/I, mob/user as mob)
|
||||
..()
|
||||
if(istype(I, /obj/item/stack/packageWrap))
|
||||
var/obj/item/stack/packageWrap/C = I
|
||||
if (C.use(5))
|
||||
var/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/W = new /obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised
|
||||
user.unEquip(src)
|
||||
user.put_in_hands(W)
|
||||
user << "<span class='notice'>You tie the wrapping paper around the stock and the barrel to secure it.</span>"
|
||||
qdel(src)
|
||||
else
|
||||
user << "<span class='warning'>You need at least five feet of wrapping paper to secure the stock.</span>"
|
||||
return
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
/datum/table_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
|
||||
var/tools[] = list() //type paths of items needed but not consumed
|
||||
var/time = 30 //time in deciseconds
|
||||
var/parts[] = list() //type paths of items that will be placed in the result
|
||||
var/chem_catalists[] = list() //like tools but for reagents
|
||||
|
||||
|
||||
/datum/table_recipe/IED
|
||||
name = "IED"
|
||||
result = /obj/item/weapon/grenade/iedcasing
|
||||
reqs = list(/datum/reagent/fuel = 50,
|
||||
/obj/item/stack/cable_coil = 1,
|
||||
/obj/item/device/assembly/igniter = 1,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans = 1)
|
||||
parts = list(/obj/item/weapon/reagent_containers/food/drinks/cans = 1)
|
||||
time = 80
|
||||
|
||||
/datum/table_recipe/stunprod
|
||||
name = "Stunprod"
|
||||
result = /obj/item/weapon/melee/baton/cattleprod
|
||||
reqs = list(/obj/item/weapon/restraints/handcuffs/cable = 1,
|
||||
/obj/item/stack/rods = 1,
|
||||
/obj/item/weapon/wirecutters = 1,
|
||||
/obj/item/weapon/stock_parts/cell = 1)
|
||||
time = 80
|
||||
parts = list(/obj/item/weapon/stock_parts/cell = 1)
|
||||
|
||||
/datum/table_recipe/ed209
|
||||
name = "ED209"
|
||||
result = /obj/machinery/bot/ed209
|
||||
reqs = list(/obj/item/robot_parts/robot_suit = 1,
|
||||
/obj/item/clothing/head/helmet = 1,
|
||||
/obj/item/clothing/suit/armor/vest = 1,
|
||||
/obj/item/robot_parts/l_leg = 1,
|
||||
/obj/item/robot_parts/r_leg = 1,
|
||||
/obj/item/stack/sheet/metal = 5,
|
||||
/obj/item/stack/cable_coil = 5,
|
||||
/obj/item/weapon/gun/energy/advtaser = 1,
|
||||
/obj/item/weapon/stock_parts/cell = 1,
|
||||
/obj/item/device/assembly/prox_sensor = 1,
|
||||
/obj/item/robot_parts/r_arm = 1)
|
||||
tools = list(/obj/item/weapon/weldingtool, /obj/item/weapon/screwdriver)
|
||||
time = 120
|
||||
|
||||
/datum/table_recipe/secbot
|
||||
name = "Secbot"
|
||||
result = /obj/machinery/bot/secbot
|
||||
reqs = list(/obj/item/device/assembly/signaler = 1,
|
||||
/obj/item/clothing/head/helmet = 1,
|
||||
/obj/item/weapon/melee/baton = 1,
|
||||
/obj/item/device/assembly/prox_sensor = 1,
|
||||
/obj/item/robot_parts/r_arm = 1)
|
||||
tools = list(/obj/item/weapon/weldingtool)
|
||||
time = 120
|
||||
|
||||
/datum/table_recipe/cleanbot
|
||||
name = "Cleanbot"
|
||||
result = /obj/machinery/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
|
||||
|
||||
/datum/table_recipe/floorbot
|
||||
name = "Floorbot"
|
||||
result = /obj/machinery/bot/floorbot
|
||||
reqs = list(/obj/item/weapon/storage/toolbox/mechanical = 1,
|
||||
/obj/item/stack/tile/plasteel = 1,
|
||||
/obj/item/device/assembly/prox_sensor = 1,
|
||||
/obj/item/robot_parts/r_arm = 1)
|
||||
time = 80
|
||||
|
||||
/datum/table_recipe/medbot
|
||||
name = "Medbot"
|
||||
result = /obj/machinery/bot/medbot
|
||||
reqs = list(/obj/item/device/healthanalyzer = 1,
|
||||
/obj/item/weapon/storage/firstaid = 1,
|
||||
/obj/item/device/assembly/prox_sensor = 1,
|
||||
/obj/item/robot_parts/r_arm = 1)
|
||||
time = 80
|
||||
|
||||
/datum/table_recipe/flamethrower
|
||||
name = "Flamethrower"
|
||||
result = /obj/item/weapon/flamethrower
|
||||
reqs = list(/obj/item/weapon/weldingtool = 1,
|
||||
/obj/item/device/assembly/igniter = 1,
|
||||
/obj/item/stack/rods = 2)
|
||||
tools = list(/obj/item/weapon/screwdriver)
|
||||
time = 20
|
||||
|
||||
/datum/table_recipe/meteorshot
|
||||
name = "Meteorshot Shell"
|
||||
result = /obj/item/ammo_casing/shotgun/meteorshot
|
||||
reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
|
||||
/obj/item/weapon/rcd_ammo = 1,
|
||||
/obj/item/weapon/stock_parts/manipulator = 2)
|
||||
tools = list(/obj/item/weapon/screwdriver)
|
||||
time = 5
|
||||
|
||||
/datum/table_recipe/pulseslug
|
||||
name = "Pulse Slug Shell"
|
||||
result = /obj/item/ammo_casing/shotgun/pulseslug
|
||||
reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
|
||||
/obj/item/weapon/stock_parts/capacitor/adv = 2,
|
||||
/obj/item/weapon/stock_parts/micro_laser/ultra = 1)
|
||||
tools = list(/obj/item/weapon/screwdriver)
|
||||
time = 5
|
||||
|
||||
/datum/table_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
|
||||
|
||||
/datum/table_recipe/frag12
|
||||
name = "FRAG-12 Shell"
|
||||
result = /obj/item/ammo_casing/shotgun/frag12
|
||||
reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
|
||||
/datum/reagent/glycerol = 5,
|
||||
/datum/reagent/sacid = 5,
|
||||
/datum/reagent/pacid = 5,)
|
||||
tools = list(/obj/item/weapon/screwdriver)
|
||||
time = 5
|
||||
|
||||
/datum/table_recipe/ishotgun
|
||||
name = "Improvised Shotgun"
|
||||
result = /obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised
|
||||
reqs = list(/obj/item/weaponcrafting/receiver = 1,
|
||||
/obj/item/pipe = 1,
|
||||
/obj/item/weaponcrafting/stock = 1,
|
||||
/obj/item/stack/packageWrap = 5,)
|
||||
tools = list(/obj/item/weapon/screwdriver)
|
||||
time = 200
|
||||
@@ -0,0 +1,200 @@
|
||||
#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:
|
||||
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))
|
||||
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))
|
||||
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()
|
||||
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
|
||||
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())
|
||||
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))
|
||||
usr << "<span class='notice'>[TR.name] constructed.</span>"
|
||||
else
|
||||
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
|
||||
Reference in New Issue
Block a user