diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm
index f1aae4943e3..25c7b2e0b24 100644
--- a/code/game/machinery/constructable_frame.dm
+++ b/code/game/machinery/constructable_frame.dm
@@ -30,47 +30,6 @@
var/obj/O = new path()
req_component_names[tname] = O.name
-/obj/machinery/constructable_frame/proc/find_square()
- // This is fucking stupid but what the hell.
-
- // This corresponds to indicies from alldirs.
- // 1 2 3 4 5 6 7 8
- // var/list/alldirs = list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)
- var/valid_patterns=list(
- list(1,3,5), //SW - NORTH,EAST,NORTHEAST
- list(2,3,7), //NW - SOUTH,EAST,SOUTHEAST
- list(1,4,6), //SE - NORTH,WEST,NORTHWEST
- list(2,4,8) //NE - SOUTH,WEST,SOUTHWEST
- )
- var/detected_parts[8]
- var/tally=0
- var/turf/T
- var/obj/machinery/constructable_frame/machine_frame/friend
- for(var/i=1;i<=8;i++)
- T=get_step(src.loc,alldirs[i])
- friend = locate() in T
- if(friend)
- detected_parts[i]=friend
- tally++
- // Need at least 3 connections to make a square
- if(tally<3)
- return
- // Find stuff in the patterns indicated
- for(var/i=1;i<=4;i++)
- var/list/scanidxs=valid_patterns[i]
- var/list/new_connected=list()
- var/allfound=1
- for(var/diridx in scanidxs)
- if(detected_parts[diridx]==null)
- allfound=0
- break
- new_connected.Add(detected_parts[diridx])
- if(allfound)
- connected_parts=new_connected
- pattern_idx=i
- return 1
- return 0
-
// update description of required components remaining
/obj/machinery/constructable_frame/proc/update_req_desc()
if(!req_components || !req_component_names)
@@ -123,35 +82,7 @@
new /obj/structure/displaycase_frame(src.loc)
del(src)
return
- else if(istype(P, /obj/item/stack/rods))
- var/obj/item/stack/rods/R=P
- if(R.amount<10)
- user << "\red You need 10 rods to assemble a pod frame."
- return
- if(!find_square())
- user << "\red You cannot assemble a pod frame without a 2x2 square of machine frames."
- return
- R.use(10)
-
- for(var/obj/machinery/constructable_frame/machine_frame/F in connected_parts)
- qdel(F)
-
- var/turf/T=get_turf(src)
- // Offset frame (if needed) so it doesn't look wonky when it spawns.
- switch(pattern_idx)
- if(2)
- T=get_step(T,SOUTH)
- if(3)
- T=get_step(T,WEST)
- if(4)
- T=get_step(T,SOUTHWEST)
-
- new /obj/structure/spacepod_frame(T)
- user << "\blue You assemble the pod frame."
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
- qdel(src)
- return
if(istype(P, /obj/item/weapon/wrench))
playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
user << "You dismantle the frame."
@@ -485,6 +416,18 @@ obj/item/weapon/circuitboard/rdserver
/obj/item/weapon/stock_parts/micro_laser = 1,
/obj/item/weapon/stock_parts/console_screen = 1)
+/obj/item/weapon/circuitboard/podfab
+ name = "Circuit board (Spacepod Fabricator)"
+ build_path = "/obj/machinery/r_n_d/fabricator/pod"
+ board_type = "machine"
+ origin_tech = "programming=3;engineering=3"
+ frame_desc = "Requires 3 Matter Bins, 2 Manipulators, and 2 Micro-Lasers."
+ req_components = list(
+ "/obj/item/weapon/stock_parts/matter_bin" = 3,
+ "/obj/item/weapon/stock_parts/manipulator" = 2,
+ "/obj/item/weapon/stock_parts/micro_laser" = 2)
+
+
/obj/item/weapon/circuitboard/clonepod
name = "Circuit board (Clone Pod)"
build_path = "/obj/machinery/clonepod"
diff --git a/code/game/vehicles/spacepods/construction.dm b/code/game/vehicles/spacepods/construction.dm
index aac72fc0e99..478a064021f 100644
--- a/code/game/vehicles/spacepods/construction.dm
+++ b/code/game/vehicles/spacepods/construction.dm
@@ -102,6 +102,7 @@
),
state_next = list(
"key" = /obj/item/pod_parts/core,
+ ,
"vis_msg" = "{USER} inserts the core into the {HOLDER}.",
"self_msg" = "You carefully insert the core into the {HOLDER}.",
"delete" = 1
@@ -179,10 +180,10 @@
"self_msg" = "You cut the {HOLDER}'s bulkhead panelling loose."
),
state_next = list(
- "key" = /obj/item/stack/sheet/plasteel,
- "amount" = 5,
- "vis_msg" = "{USER} installs the {HOLDER}'s plasteel armor.",
- "self_msg" = "You install the {HOLDER}'s plasteel armor."
+ "key" = /obj/item/pod_parts/armor,
+ "vis_msg" = "{USER} installs the {HOLDER}'s armor plating.",
+ "self_msg" = "You install the {HOLDER}'s armor plating.",
+ "delete" = 1
)
),
// 11. Loose armor
@@ -191,7 +192,9 @@
state_prev = list(
"key" = /obj/item/weapon/crowbar,
"vis_msg" = "{USER} pries off {HOLDER}'s armor.",
- "self_msg" = "You pry off {HOLDER}'s armor."
+ "self_msg" = "You pry off {HOLDER}'s armor.",
+ "spawn" = /obj/item/pod_parts/armor,
+ "amount" = 1
),
state_next = list(
"key" = /obj/item/weapon/wrench,
diff --git a/code/game/vehicles/spacepods/parts.dm b/code/game/vehicles/spacepods/parts.dm
index 02624769364..19210fc2b9a 100644
--- a/code/game/vehicles/spacepods/parts.dm
+++ b/code/game/vehicles/spacepods/parts.dm
@@ -1,10 +1,126 @@
/obj/item/pod_parts
parent_type = /obj/item/mecha_parts
- icon = 'icons/pods/equipment.dmi'
+ icon = 'icons/pods/pod_parts.dmi'
/obj/item/pod_parts/core
name="Space Pod Core"
icon_state = "core"
construction_cost = list("iron"=5000,"uranium"=1000,"plasma"=5000)
flags = CONDUCT
- origin_tech = "programming=2;materials=3;bluespace=2;engineering=3"
\ No newline at end of file
+ origin_tech = "programming=2;materials=3;bluespace=2;engineering=3"
+
+/obj/item/pod_parts/pod_frame
+ name = "Space Pod Frame"
+ icon_state = ""
+ flags = CONDUCT
+ density = 0
+ anchored = 0
+ var/link_to = null
+ var/link_angle = 0
+
+/obj/item/pod_parts/pod_frame/proc/find_square()
+ /*
+ each part, in essence, stores the relative position of another part
+ you can find where this part should be by looking at the current direction of the current part and applying the link_angle
+ the link_angle is the angle between the part's direction and its following part, which is the current part's link_to
+ the code works by going in a loop - each part is capable of starting a loop by checking for the part after it, and that part checking, and so on
+ this 4-part loop, starting from any part of the frame, can determine if all the parts are properly in place and aligned
+ it also checks that each part is unique, and that all the parts are there for the spacepod itself
+ */
+ var/neededparts = list(/obj/item/pod_parts/pod_frame/aft_port, /obj/item/pod_parts/pod_frame/aft_starboard, /obj/item/pod_parts/pod_frame/fore_port, /obj/item/pod_parts/pod_frame/fore_starboard)
+ var/turf/T
+ var/obj/item/pod_parts/pod_frame/linked
+ var/obj/item/pod_parts/pod_frame/pointer
+ var/connectedparts = list()
+ neededparts -= src
+ //log_admin("Starting with [src]")
+ linked = src
+ for(var/i = 1; i <= 4; i++)
+ T = get_turf(get_step(linked, turn(linked.dir, -linked.link_angle))) //get the next place that we want to look at
+ if(locate(linked.link_to) in T)
+ pointer = locate(linked.link_to) in T
+ //log_admin("Looking at [pointer.type]")
+ if(istype(pointer, linked.link_to) && pointer.dir == linked.dir && pointer.anchored)
+ if(!(pointer in connectedparts))
+ connectedparts += pointer
+ linked = pointer
+ pointer = null
+ //log_admin("Parts left: [neededparts.len]") //len not working
+ for(var/i = 1; i <=4; i++)
+ var/obj/item/pod_parts/pod_frame/F = connectedparts[i]
+ if(F.type in neededparts) //if one of the items can be founded in neededparts
+ neededparts -= F.type
+ log_admin("Found [F.type]")
+ else //because neededparts has 4 distinct items, this must be called if theyre not all in place and wrenched
+ return 0
+ return connectedparts
+
+/obj/item/pod_parts/pod_frame/attackby(var/obj/O, mob/user)
+ if(istype(O, /obj/item/stack/rods))
+ var/obj/item/stack/rods/R = O
+ var/list/linkedparts = find_square()
+ if(!linkedparts)
+ user << "You cannot assemble a pod frame because you do not have the necessary assembly."
+ return
+ var/obj/structure/spacepod_frame/pod = new /obj/structure/spacepod_frame(src.loc)
+ pod.dir = src.dir
+ user << "You strut the pod frame together."
+ R.use(10)
+ for(var/obj/item/pod_parts/pod_frame/F in linkedparts)
+ if(1 == turn(F.dir, -F.link_angle)) //if the part links north during construction, as the bottom left part always does
+ //log_admin("Repositioning")
+ pod.loc = F.loc
+ qdel(F)
+ playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
+ if(istype(O, /obj/item/weapon/wrench))
+ user << "You [!anchored ? "secure \the [src] in place." : "remove the securing bolts."]"
+ anchored = !anchored
+ density = anchored
+ playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
+
+/obj/item/pod_parts/pod_frame/verb/rotate()
+ set name = "Rotate Frame"
+ set category = "Object"
+ set src in oview(1)
+ if(anchored)
+ usr << "\The [src] is securely bolted!"
+ return 0
+ src.dir = turn(src.dir, -90)
+ return 1
+
+/obj/item/pod_parts/pod_frame/attack_hand()
+ src.rotate()
+
+/obj/item/pod_parts/pod_frame/fore_port
+ name = "fore port pod frame"
+ icon_state = "pod_fp"
+ desc = "A space pod frame component. This is the fore port component."
+ link_to = /obj/item/pod_parts/pod_frame/fore_starboard
+ link_angle = 90
+
+/obj/item/pod_parts/pod_frame/fore_starboard
+ name = "fore starboard pod frame"
+ icon_state = "pod_fs"
+ desc = "A space pod frame component. This is the fore starboard component."
+ link_to = /obj/item/pod_parts/pod_frame/aft_starboard
+ link_angle = 180
+
+/obj/item/pod_parts/pod_frame/aft_port
+ name = "aft port pod frame"
+ icon_state = "pod_ap"
+ desc = "A space pod frame component. This is the aft port component."
+ link_to = /obj/item/pod_parts/pod_frame/fore_port
+ link_angle = 0
+
+/obj/item/pod_parts/pod_frame/aft_starboard
+ name = "aft starboard pod frame"
+ icon_state = "pod_as"
+ desc = "A space pod frame component. This is the aft starboard component."
+ link_to = /obj/item/pod_parts/pod_frame/aft_port
+ link_angle = 270
+
+/obj/item/pod_parts/armor
+ name = "civilian pod armor"
+ icon = 'icons/pods/pod_parts.dmi'
+ icon_state = "pod_armor_civ"
+ desc = "Spacepod armor. This is the civilian version. It looks rather flimsy."
\ No newline at end of file
diff --git a/code/game/vehicles/spacepods/pod_fabricator.dm b/code/game/vehicles/spacepods/pod_fabricator.dm
new file mode 100644
index 00000000000..f605f2f588b
--- /dev/null
+++ b/code/game/vehicles/spacepods/pod_fabricator.dm
@@ -0,0 +1,559 @@
+/obj/machinery/spod_part_fabricator
+ icon = 'icons/obj/robotics.dmi'
+ icon_state = "fab-idle"
+ name = "spacepod fabricator"
+ desc = "Nothing is being built."
+ density = 1
+ anchored = 1
+ use_power = 1
+ idle_power_usage = 20
+ active_power_usage = 5000
+ req_access = list(access_robotics)
+ var/time_coeff = 1
+ var/resource_coeff = 1
+ var/time_coeff_tech = 1
+ var/resource_coeff_tech = 1
+ var/list/resources = list(
+ "$metal"=0,
+ "$glass"=0,
+ "$bananium"=0,
+ "$diamond"=0,
+ "$gold"=0,
+ "$plasma"=0,
+ "$silver"=0,
+ "$uranium"=0
+ )
+ var/res_max_amount = 200000
+ var/datum/research/files
+ var/id
+ var/sync = 0
+ var/part_set
+ var/datum/design/being_built
+ var/list/queue = list()
+ var/processing_queue = 0
+ var/screen = "main"
+ var/temp
+ var/list/part_sets = list(
+ "Pod_Weaponry",
+ "Pod_Armor",
+ "Pod_Parts",
+ "Pod_Frame",
+ "Misc",
+ )
+
+/obj/machinery/spod_part_fabricator/New()
+ ..()
+ component_parts = list()
+ component_parts += new /obj/item/weapon/circuitboard/podfab(null)
+ component_parts += new /obj/item/weapon/stock_parts/matter_bin(null)
+ component_parts += new /obj/item/weapon/stock_parts/matter_bin(null)
+ component_parts += new /obj/item/weapon/stock_parts/manipulator(null)
+ component_parts += new /obj/item/weapon/stock_parts/micro_laser(null)
+ component_parts += new /obj/item/weapon/stock_parts/console_screen(null)
+ RefreshParts()
+ files = new /datum/research(src) //Setup the research data holder.
+
+/obj/machinery/spod_part_fabricator/upgraded/New()
+ ..()
+ component_parts = list()
+ component_parts += new /obj/item/weapon/circuitboard/podfab(null)
+ component_parts += new /obj/item/weapon/stock_parts/matter_bin/super(null)
+ component_parts += new /obj/item/weapon/stock_parts/matter_bin/super(null)
+ component_parts += new /obj/item/weapon/stock_parts/manipulator/pico(null)
+ component_parts += new /obj/item/weapon/stock_parts/micro_laser/ultra(null)
+ component_parts += new /obj/item/weapon/stock_parts/console_screen(null)
+ RefreshParts()
+
+/obj/machinery/spod_part_fabricator/RefreshParts()
+ var/T = 0
+
+ //maximum stocking amount (max 412000)
+ for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts)
+ T += M.rating
+ res_max_amount = (187000+(T * 37500))
+
+ //ressources adjustment coefficient (1 -> 0.88 -> 0.75)
+ T = -1
+ for(var/obj/item/weapon/stock_parts/micro_laser/Ma in component_parts)
+ T += Ma.rating
+ resource_coeff = round(initial(resource_coeff) - (initial(resource_coeff)*(T))/8,0.01)
+
+ //building time adjustment coefficient (1 -> 0.8 -> 0.6)
+ T = -1
+ for(var/obj/item/weapon/stock_parts/manipulator/Ml in component_parts)
+ T += Ml.rating
+ time_coeff = round(initial(time_coeff) - (initial(time_coeff)*(T))/5,0.01)
+
+
+/obj/machinery/spod_part_fabricator/check_access(obj/item/weapon/card/id/I)
+ if(istype(I, /obj/item/device/pda))
+ var/obj/item/device/pda/pda = I
+ I = pda.id
+ if(!istype(I) || !I.access) //not ID or no access
+ return 0
+ for(var/req in req_access)
+ if(!(req in I.access)) //doesn't have this access
+ return 0
+ return 1
+
+/obj/machinery/spod_part_fabricator/proc/emag()
+ switch(emagged)
+ if(0)
+ emagged = 0.5
+ visible_message("\icon[src] \The [src] beeps: \"DB error \[Code 0x00F1\]\"")
+ sleep(10)
+ visible_message("\icon[src] \The [src] beeps: \"Attempting auto-repair\"")
+ sleep(15)
+ visible_message("\icon[src] \The [src] beeps: \"User DB corrupted \[Code 0x00FA\]. Truncating data structure...\"")
+ sleep(30)
+ visible_message("\icon[src] \The [src] beeps: \"User DB truncated. Please contact your Nanotrasen system operator for future assistance.\"")
+ req_access = null
+ emagged = 1
+ if(0.5)
+ visible_message("\icon[src] \The [src] beeps: \"DB not responding \[Code 0x0003\]...\"")
+ if(1)
+ visible_message("\icon[src] \The [src] beeps: \"No records in User DB\"")
+ return
+
+/obj/machinery/spod_part_fabricator/proc/output_parts_list(set_name)
+ var/output = ""
+ for(var/datum/design/D in files.known_designs)
+ if(D.build_type & PODFAB)
+ if(!(set_name in D.category))
+ continue
+ var/resources_available = check_resources(D)
+ output += "
"
+ return output
+
+/obj/machinery/spod_part_fabricator/proc/output_part_info(datum/design/D)
+ var/output = "[initial(D.name)] (Cost: [output_part_cost(D)]) [get_construction_time_w_coeff(D)/10] seconds"
+ return output
+
+/obj/machinery/spod_part_fabricator/proc/output_part_cost(datum/design/D)
+ var/i = 0
+ var/output
+ for(var/c in D.materials)
+ if(c in resources)
+ output += "[i?" | ":null][get_resource_cost_w_coeff(D,c)] [material2name(c)]"
+ i++
+ return output
+
+/obj/machinery/spod_part_fabricator/proc/output_available_resources()
+ var/output
+ for(var/resource in resources)
+ var/amount = min(res_max_amount, resources[resource])
+ output += "[material2name(resource)]: [amount] cm³"
+ if(amount>0)
+ output += " - Remove \[1\] | \[10\] | \[All\]"
+ output += "
"
+ return output
+
+/obj/machinery/spod_part_fabricator/proc/remove_resources(datum/design/D)
+ for(var/resource in D.materials)
+ if(resource in resources)
+ resources[resource] -= get_resource_cost_w_coeff(D,resource)
+
+/obj/machinery/spod_part_fabricator/proc/check_resources(datum/design/D)
+ for(var/R in D.materials)
+ if(R in resources)
+ if(resources[R] < get_resource_cost_w_coeff(D, R))
+ return 0
+ else
+ return 0
+ return 1
+
+/obj/machinery/spod_part_fabricator/proc/build_part(datum/design/D)
+ being_built = D
+ desc = "It's building \a [initial(D.name)]."
+ remove_resources(D)
+ overlays += "fab-active"
+ use_power = 2
+ updateUsrDialog()
+ sleep(get_construction_time_w_coeff(D))
+ use_power = 1
+ overlays -= "fab-active"
+ desc = initial(desc)
+
+ var/obj/item/I = new D.build_path
+ I.loc = get_step(src,SOUTH)
+ I.m_amt = get_resource_cost_w_coeff(D,"$metal")
+ I.g_amt = get_resource_cost_w_coeff(D,"$glass")
+ visible_message("\icon[src] \The [src] beeps, \"\The [I] is complete.\"")
+ being_built = null
+
+ updateUsrDialog()
+ return 1
+
+/obj/machinery/spod_part_fabricator/proc/update_queue_on_page()
+ send_byjax(usr,"mecha_fabricator.browser","queue",list_queue())
+ return
+
+/obj/machinery/spod_part_fabricator/proc/add_part_set_to_queue(set_name)
+ if(set_name in part_sets)
+ for(var/datum/design/D in files.known_designs)
+ if(D.build_type & PODFAB)
+ if(set_name in D.category)
+ add_to_queue(D)
+
+/obj/machinery/spod_part_fabricator/proc/add_to_queue(D)
+ if(!istype(queue))
+ queue = list()
+ if(D)
+ queue[++queue.len] = D
+ return queue.len
+
+/obj/machinery/spod_part_fabricator/proc/remove_from_queue(index)
+ if(!isnum(index) || !istype(queue) || (index<1 || index>queue.len))
+ return 0
+ queue.Cut(index,++index)
+ return 1
+
+/obj/machinery/spod_part_fabricator/proc/process_queue()
+ var/datum/design/D = queue[1]
+ if(!D)
+ remove_from_queue(1)
+ if(queue.len)
+ return process_queue()
+ else
+ return
+ temp = null
+ while(D)
+ if(stat&(NOPOWER|BROKEN))
+ return 0
+ if(!check_resources(D))
+ visible_message("\icon[src] \The [src] beeps, \"Not enough resources. Queue processing stopped.\"")
+ temp = {"Not enough resources to build next part.
+ Try again | Return"}
+ return 0
+ remove_from_queue(1)
+ build_part(D)
+ D = listgetindex(queue, 1)
+ visible_message("\icon[src] \The [src] beeps, \"Queue processing finished successfully.\"")
+
+/obj/machinery/spod_part_fabricator/proc/list_queue()
+ var/output = "Queue contains:"
+ if(!istype(queue) || !queue.len)
+ output += "
Nothing"
+ else
+ output += ""
+ var/i = 0
+ for(var/datum/design/D in queue)
+ i++
+ var/obj/part = D.build_path
+ output += "- [initial(part.name)] - [i>1?"↑":null] [i↓
":null] Remove"
+
+ output += ""
+ output += "\[Process queue | Clear queue\]"
+ return output
+
+/obj/machinery/spod_part_fabricator/proc/update_tech()
+ if(!files)
+ return
+ var/output
+ for(var/datum/tech/T in files.known_tech)
+ if(T && T.level > 1)
+ var/diff
+ switch(T.id)
+ if("materials")
+ //one materials level is 1/32, so that max level is 0.75 coefficient
+ diff = round(initial(resource_coeff_tech) - (initial(resource_coeff_tech)*(T.level-1))/32,0.01)
+ if(resource_coeff_tech>diff)
+ resource_coeff_tech = diff
+ output+="Production efficiency increased.
"
+ if("programming")
+ //one materials level is 1/40, so that max level is 0.8 coefficient
+ diff = round(initial(time_coeff_tech) - (initial(time_coeff_tech)*(T.level-1))/40,0.1)
+ if(time_coeff_tech>diff)
+ time_coeff_tech = diff
+ output+="Production routines updated.
"
+ return output
+
+
+/obj/machinery/spod_part_fabricator/proc/sync()
+ temp = "Updating local R&D database..."
+ updateUsrDialog()
+ sleep(30) //only sleep if called by user
+
+ for(var/obj/machinery/computer/rdconsole/RDC in area_contents(get_area(src)))
+ if(!RDC.sync)
+ continue
+ for(var/datum/tech/T in RDC.files.known_tech)
+ files.AddTech2Known(T)
+ for(var/datum/design/D in RDC.files.known_designs)
+ files.AddDesign2Known(D)
+ files.RefreshResearch()
+ temp = "Processed equipment designs.
"
+ //check if the tech coefficients have changed
+ temp += update_tech()
+ temp += "Return"
+
+ updateUsrDialog()
+ visible_message("\icon[src] \The [src] beeps, \"Successfully synchronized with R&D server.\"")
+ return
+
+ temp = "Unable to connect to local R&D Database.
Please check your connections and try again.
Return"
+ updateUsrDialog()
+ return
+
+/obj/machinery/spod_part_fabricator/proc/get_resource_cost_w_coeff(datum/design/D, resource, roundto = 1)
+ return round(D.materials[resource]*resource_coeff*resource_coeff_tech, roundto)
+
+/obj/machinery/spod_part_fabricator/proc/get_construction_time_w_coeff(datum/design/D, roundto = 1) //aran
+ return round(initial(D.construction_time)*time_coeff*time_coeff_tech, roundto)
+
+/obj/machinery/spod_part_fabricator/attack_hand(mob/user)
+ if(!(..()))
+ return interact(user)
+
+/obj/machinery/spod_part_fabricator/interact(mob/user as mob)
+ var/dat, left_part
+ if (..())
+ return
+ user.set_machine(src)
+ var/turf/exit = get_step(src,SOUTH)
+ if(exit.density)
+ visible_message("\icon[src] \The [src] beeps, \"Error! Part outlet is obstructed.\"")
+ return
+ if(temp)
+ left_part = temp
+ else if(being_built)
+ var/obj/I = being_built.build_path
+ left_part = {"Building [initial(I.name)].
+ Please wait until completion..."}
+ else
+ switch(screen)
+ if("main")
+ left_part = output_available_resources()+"
"
+ left_part += "Sync with R&D servers
"
+ for(var/part_set in part_sets)
+ left_part += "[part_set] - \[Add all parts to queue\]
"
+ if("parts")
+ left_part += output_parts_list(part_set)
+ left_part += "
Return"
+ dat = {"
+
+ [name]
+
+
+
+
+
+
+ |
+ [left_part]
+ |
+
+ [list_queue()]
+ |
+
+
+
+ "}
+ user << browse(dat, "window=mecha_fabricator;size=1000x430")
+ onclose(user, "mecha_fabricator")
+ return
+
+/obj/machinery/spod_part_fabricator/Topic(href, href_list)
+ if(..())
+ return
+ var/datum/topic_input/filter = new /datum/topic_input(href,href_list)
+ if(href_list["part_set"])
+ var/tpart_set = filter.getStr("part_set")
+ if(tpart_set)
+ if(tpart_set=="clear")
+ part_set = null
+ else
+ part_set = tpart_set
+ screen = "parts"
+ if(href_list["part"])
+ var/T = filter.getStr("part")
+ for(var/datum/design/D in files.known_designs)
+ if(D.build_type & PODFAB)
+ if(D.id == T)
+ if(!processing_queue)
+ build_part(D)
+ else
+ add_to_queue(D)
+ break
+ if(href_list["add_to_queue"])
+ var/T = filter.getStr("add_to_queue")
+ for(var/datum/design/D in files.known_designs)
+ if(D.build_type & PODFAB)
+ if(D.id == T)
+ add_to_queue(D)
+ break
+ return update_queue_on_page()
+ if(href_list["remove_from_queue"])
+ remove_from_queue(filter.getNum("remove_from_queue"))
+ return update_queue_on_page()
+ if(href_list["partset_to_queue"])
+ add_part_set_to_queue(filter.get("partset_to_queue"))
+ return update_queue_on_page()
+ if(href_list["process_queue"])
+ spawn(-1)
+ if(processing_queue || being_built)
+ return 0
+ processing_queue = 1
+ process_queue()
+ processing_queue = 0
+ if(href_list["clear_temp"])
+ temp = null
+ if(href_list["screen"])
+ screen = href_list["screen"]
+ if(href_list["queue_move"] && href_list["index"])
+ var/index = filter.getNum("index")
+ var/new_index = index + filter.getNum("queue_move")
+ if(isnum(index) && isnum(new_index))
+ if(IsInRange(new_index,1,queue.len))
+ queue.Swap(index,new_index)
+ return update_queue_on_page()
+ if(href_list["clear_queue"])
+ queue = list()
+ return update_queue_on_page()
+ if(href_list["sync"])
+ sync()
+ if(href_list["part_desc"])
+ var/T = filter.getStr("part_desc")
+ for(var/datum/design/D in files.known_designs)
+ if(D.build_type & PODFAB)
+ if(D.id == T)
+ var/obj/part = D.build_path
+ temp = {"[initial(part.name)] description:
+ [initial(part.desc)]
+ Return
+ "}
+ break
+
+ if(href_list["remove_mat"] && href_list["material"])
+ var/amount = text2num(href_list["remove_mat"])
+ var/material = href_list["material"]
+ if(amount < 0 || amount > resources[material]) //href protection
+ return
+
+ var/removed = remove_material(material,amount)
+ if(removed == -1)
+ temp = "Not enough [material2name(material)] to produce a sheet."
+ else
+ temp = "Ejected [removed] of [material2name(material)]"
+ temp += "
Return"
+
+ updateUsrDialog()
+ return
+
+/obj/machinery/spod_part_fabricator/proc/remove_material(var/mat_string, var/amount)
+ if(resources[mat_string] < MINERAL_MATERIAL_AMOUNT) //not enough mineral for a sheet
+ return -1
+ var/type
+ switch(mat_string)
+ if("$metal")
+ type = /obj/item/stack/sheet/metal
+ if("$glass")
+ type = /obj/item/stack/sheet/glass
+ if("$gold")
+ type = /obj/item/stack/sheet/mineral/gold
+ if("$silver")
+ type = /obj/item/stack/sheet/mineral/silver
+ if("$diamond")
+ type = /obj/item/stack/sheet/mineral/diamond
+ if("$plasma")
+ type = /obj/item/stack/sheet/mineral/plasma
+ if("$uranium")
+ type = /obj/item/stack/sheet/mineral/uranium
+ if("$bananium")
+ type = /obj/item/stack/sheet/mineral/clown
+ else
+ return 0
+ var/result = 0
+
+ while(amount > 50)
+ new type(get_turf(src),50)
+ amount -= 50
+ result += 50
+ resources[mat_string] -= 50 * MINERAL_MATERIAL_AMOUNT
+
+ var/total_amount = round(resources[mat_string]/MINERAL_MATERIAL_AMOUNT)
+ if(total_amount)//if there's still enough material for sheets
+ var/obj/item/stack/sheet/res = new type(get_turf(src),min(amount,total_amount))
+ resources[mat_string] -= res.amount*MINERAL_MATERIAL_AMOUNT
+ result += res.amount
+
+ return result
+
+
+/obj/machinery/spod_part_fabricator/attackby(obj/W as obj, mob/user as mob, params)
+ if(default_deconstruction_screwdriver(user, "fab-o", "fab-idle", W))
+ return
+
+ if(exchange_parts(user, W))
+ return
+
+ if(panel_open)
+ if(istype(W, /obj/item/weapon/crowbar))
+ for(var/material in resources)
+ remove_material(material, resources[material]/MINERAL_MATERIAL_AMOUNT)
+ default_deconstruction_crowbar(W)
+ return 1
+ else
+ user << "You can't load \the [name] while it's opened."
+ return 1
+
+ if(istype(W, /obj/item/stack))
+ var/material
+ switch(W.type)
+ if(/obj/item/stack/sheet/mineral/gold)
+ material = "$gold"
+ if(/obj/item/stack/sheet/mineral/silver)
+ material = "$silver"
+ if(/obj/item/stack/sheet/mineral/diamond)
+ material = "$diamond"
+ if(/obj/item/stack/sheet/mineral/plasma)
+ material = "$plasma"
+ if(/obj/item/stack/sheet/metal)
+ material = "$metal"
+ if(/obj/item/stack/sheet/glass)
+ material = "$glass"
+ if(/obj/item/stack/sheet/mineral/clown)
+ material = "$bananium"
+ if(/obj/item/stack/sheet/mineral/uranium)
+ material = "$uranium"
+ else
+ return ..()
+
+ if(being_built)
+ user << "\The [src] is currently processing. Please wait until completion."
+ return
+ if(res_max_amount - resources[material] < MINERAL_MATERIAL_AMOUNT) //overstuffing the fabricator
+ user << "\The [src] [material2name(material)] storage is full."
+ return
+ var/obj/item/stack/sheet/stack = W
+ var/sname = "[stack.name]"
+ if(resources[material] < res_max_amount)
+ overlays += "fab-load-[material2name(material)]"//loading animation is now an overlay based on material type. No more spontaneous conversion of all ores to metal. -vey
+
+ var/transfer_amount = min(stack.amount, round((res_max_amount - resources[material])/MINERAL_MATERIAL_AMOUNT,1))
+ resources[material] += transfer_amount * MINERAL_MATERIAL_AMOUNT
+ stack.use(transfer_amount)
+ user << "You insert [transfer_amount] [sname] sheet\s into \the [src]."
+ sleep(10)
+ updateUsrDialog()
+ overlays -= "fab-load-[material2name(material)]" //No matter what the overlay shall still be deleted
+ else
+ user << "\The [src] cannot hold any more [sname] sheet\s."
+ return
+
+/obj/machinery/spod_part_fabricator/emag_act(user as mob)
+ emag()
+
+/obj/machinery/spod_part_fabricator/proc/material2name(var/ID)
+ return copytext(ID,2)
\ No newline at end of file
diff --git a/code/modules/research/designs/mecha_designs.dm b/code/modules/research/designs/mecha_designs.dm
index b201db4fa47..f1f58a0ca0e 100644
--- a/code/modules/research/designs/mecha_designs.dm
+++ b/code/modules/research/designs/mecha_designs.dm
@@ -166,14 +166,3 @@
materials = list("$glass" = 1000, "sacid" = 20)
build_path = /obj/item/weapon/circuitboard/mecha/honker/targeting
category = list("Exosuit Modules")
-
-// Space pod
-/datum/design/spacepod_main
- name = "Exosuit Board (Space Pod Mainboard)"
- desc = "Allows for the construction of a Space Pod mainboard."
- id = "spacepod_main"
- req_tech = list("programming" = 4)
- build_type = IMPRINTER
- materials = list("$glass" = 1000, "sacid" = 20)
- build_path = /obj/item/weapon/circuitboard/mecha/pod
- category = list("Exosuit Modules")
\ No newline at end of file
diff --git a/code/modules/research/designs/power_designs.dm b/code/modules/research/designs/power_designs.dm
index 76524f5429a..ec67de5717a 100644
--- a/code/modules/research/designs/power_designs.dm
+++ b/code/modules/research/designs/power_designs.dm
@@ -7,7 +7,7 @@
desc = "A basic power cell that holds 1000 units of energy"
id = "basic_cell"
req_tech = list("powerstorage" = 1)
- build_type = PROTOLATHE | AUTOLATHE | MECHFAB
+ build_type = PROTOLATHE | AUTOLATHE | MECHFAB | PODFAB
materials = list("$metal" = 700, "$glass" = 50)
construction_time=100
build_path = /obj/item/weapon/stock_parts/cell
@@ -18,7 +18,7 @@
desc = "A power cell that holds 10000 units of energy"
id = "high_cell"
req_tech = list("powerstorage" = 2)
- build_type = PROTOLATHE | AUTOLATHE | MECHFAB
+ build_type = PROTOLATHE | AUTOLATHE | MECHFAB | PODFAB
materials = list("$metal" = 700, "$glass" = 60)
construction_time=100
build_path = /obj/item/weapon/stock_parts/cell/high
@@ -30,7 +30,7 @@
id = "hyper_cell"
req_tech = list("powerstorage" = 5, "materials" = 4)
reliability_base = 70
- build_type = PROTOLATHE | MECHFAB
+ build_type = PROTOLATHE | MECHFAB | PODFAB
materials = list("$metal" = 400, "$gold" = 150, "$silver" = 150, "$glass" = 70)
construction_time=100
build_path = /obj/item/weapon/stock_parts/cell/hyper
@@ -42,7 +42,7 @@
id = "super_cell"
req_tech = list("powerstorage" = 3, "materials" = 2)
reliability_base = 75
- build_type = PROTOLATHE | MECHFAB
+ build_type = PROTOLATHE | MECHFAB | PODFAB
materials = list("$metal" = 700, "$glass" = 70)
construction_time=100
build_path = /obj/item/weapon/stock_parts/cell/super
diff --git a/code/modules/research/designs/spacepod_designs.dm b/code/modules/research/designs/spacepod_designs.dm
new file mode 100644
index 00000000000..932d53e0da0
--- /dev/null
+++ b/code/modules/research/designs/spacepod_designs.dm
@@ -0,0 +1,123 @@
+/datum/design/spacepod_main
+ name = "Circuit Design (Space Pod Mainboard)"
+ desc = "Allows for the construction of a Space Pod mainboard."
+ id = "spacepod_main"
+ req_tech = list("materials" = 1) //All parts required to build a basic pod have materials 1, so the mechanic can do his damn job.
+ build_type = IMPRINTER
+ materials = list("$glass" = 2000, "sacid" = 20)
+ build_path = /obj/item/weapon/circuitboard/mecha/pod
+ category = list("Misc. Machinery")
+
+//////////////////////////////////////////////////
+/////////SPACEPOD PARTS///////////////////////////
+//////////////////////////////////////////////////
+/datum/design/podframe_fp
+ construction_time = 200
+ name = "Fore port pod frame"
+ desc = "Allows for the construction of spacepod frames. This is the fore port component."
+ id = "podframefp"
+ build_type = PODFAB
+ req_tech = list("materials" = 1)
+ build_path = /obj/item/pod_parts/pod_frame/fore_port
+ category = list("Pod_Frame")
+ materials = list("$metal"=15000,"$glass"=5000)
+
+/datum/design/podframe_ap
+ construction_time = 200
+ name = "Aft port pod frame"
+ desc = "Allows for the construction of spacepod frames. This is the aft port component."
+ id = "podframeap"
+ build_type = PODFAB
+ req_tech = list("materials" = 1)
+ build_path = /obj/item/pod_parts/pod_frame/aft_port
+ category = list("Pod_Frame")
+ materials = list("$metal"=15000,"$glass"=5000)
+
+/datum/design/podframe_fs
+ construction_time = 200
+ name = "Fore starboard pod frame"
+ desc = "Allows for the construction of spacepod frames. This is the fore starboard component."
+ id = "podframefs"
+ build_type = PODFAB
+ req_tech = list("materials" = 1)
+ build_path = /obj/item/pod_parts/pod_frame/fore_starboard
+ category = list("Pod_Frame")
+ materials = list("$metal"=15000,"$glass"=5000)
+
+/datum/design/podframe_as
+ construction_time = 200
+ name = "Aft starboard pod frame"
+ desc = "Allows for the construction of spacepod frames. This is the aft starboard component."
+ id = "podframeas"
+ build_type = PODFAB
+ req_tech = list("materials" = 1)
+ build_path = /obj/item/pod_parts/pod_frame/aft_starboard
+ category = list("Pod_Frame")
+ materials = list("$metal"=15000,"$glass"=5000)
+
+//////////////////////////
+////////POD CORE////////
+//////////////////////////
+
+/datum/design/pod_core
+ construction_time = 700 //Pod core should take a bit to process, after all, it's a big complicated engine and stuff.
+ name = "Spacepod Core"
+ desc = "Allows for the construction of a spacepod core system, made up of the engine and life support systems."
+ id = "podcore"
+ build_type = MECHFAB | PODFAB
+ req_tech = list("materials" = 1)
+ build_path = /obj/item/pod_parts/core
+ category = list("Pod_Parts")
+ materials = list("$metal"=5000,"$uranium"=1000,"$plasma"=5000)
+
+//////////////////////////////////////////
+////////SPACEPOD ARMOR////////////////////
+//////////////////////////////////////////
+
+/datum/design/pod_armor_civ
+ construction_time = 400 //more time than frames, less than pod core
+ name = "Pod Armor (civilian)"
+ desc = "Allows for the construction of spacepod armor. This is the civilian version."
+ id = "podarmor_civ"
+ build_type = PODFAB
+ req_tech = list("materials" = 1)
+ build_path = /obj/item/pod_parts/armor
+ category = list("Pod_Armor")
+ materials = list("$metal"=15000,"$glass"=5000,"$plasma"=10000)
+
+//////////////////////////////////////////
+//////SPACEPOD GUNS///////////////////////
+//////////////////////////////////////////
+/datum/design/pod_gun_taser
+ construction_time = 200
+ name = "Spacepod Equipment (Taser)"
+ desc = "Allows for the construction of a spacepod mounted taser."
+ id = "podgun_taser"
+ build_type = PODFAB
+ req_tech = list("materials" = 2, "combat" = 2)
+ build_path = /obj/item/device/spacepod_equipment/weaponry/taser
+ category = list("Pod_Weaponry")
+ materials = list("$metal" = 15000)
+
+/datum/design/pod_gun_btaser
+ construction_time = 200
+ name = "Spacepod Equipment (Burst Taser)"
+ desc = "Allows for the construction of a spacepod mounted taser. This is the burst-fire model."
+ id = "podgun_btaser"
+ build_type = PODFAB
+ req_tech = list("materials" = 3, "combat" = 3)
+ build_path = /obj/item/device/spacepod_equipment/weaponry/burst_taser
+ category = list("Pod_Weaponry")
+ materials = list("$metal" = 15000)
+
+/datum/design/pod_gun_laser
+ construction_time = 200
+ name = "Spacepod Equipment (Laser)"
+ desc = "Allows for the construction of a spacepod mounted laser."
+ id = "podgun_laser"
+ build_type = PODFAB
+ req_tech = list("materials" = 3, "combat" = 3, "plasma" = 2)
+ build_path = /obj/item/device/spacepod_equipment/weaponry/laser
+ category = list("Pod_Weaponry")
+ materials = list("$metal" = 15000)
+ locked = 1
\ No newline at end of file
diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm
index 5425323b27c..28c595b8321 100644
--- a/code/modules/research/rdconsole.dm
+++ b/code/modules/research/rdconsole.dm
@@ -252,7 +252,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
screen = 2.1
else if(href_list["maxresearch"]) //Eject the item inside the destructive analyzer.
- if(!check_rights(R_ADMIN))
+ if(!check_rights(R_ADMIN))
return
screen = 0.0
if(alert("Are you sure you want to maximize research levels?","Confirmation","Yes","No")=="No")
@@ -1112,6 +1112,13 @@ won't update every console in existence) but it's more of a hassle to do. Also,
req_access = null
req_access_txt = "29"
+/obj/machinery/computer/rdconsole/mechanics
+ name = "Mechanics R&D Console"
+ desc = "A console used to interface with R&D tools."
+ id = 2
+ req_access = null
+ req_access_txt = "70"
+
/obj/machinery/computer/rdconsole/core
name = "Core R&D Console"
desc = "A console used to interface with R&D tools."
diff --git a/code/setup.dm b/code/setup.dm
index 43f1d14434f..2e9e692fa8f 100644
--- a/code/setup.dm
+++ b/code/setup.dm
@@ -953,6 +953,7 @@ var/list/hit_appends = list("-OOF", "-ACK", "-UGH", "-HRNK", "-HURGH", "-GLORF")
#define AUTOLATHE 4 //Uses glass/metal only.
#define CRAFTLATHE 8 //Uses fuck if I know. For use eventually.
#define MECHFAB 16 //Remember, objects utilising this flag should have construction_time and construction_cost vars.
+#define PODFAB 32 //Used by the spacepod part fabricator. Same idea as the mechfab
//Note: More then one of these can be added to a design but imprinter and lathe designs are incompatable.
// Suit sensor levels
diff --git a/icons/pods/equipment.dmi b/icons/pods/equipment.dmi
deleted file mode 100644
index a278e1cda45..00000000000
Binary files a/icons/pods/equipment.dmi and /dev/null differ
diff --git a/icons/pods/pod_parts.dmi b/icons/pods/pod_parts.dmi
new file mode 100644
index 00000000000..9f26446bee7
Binary files /dev/null and b/icons/pods/pod_parts.dmi differ
diff --git a/maps/cyberiad.dmm b/maps/cyberiad.dmm
index 8b7dcd0195f..527b1952eda 100644
--- a/maps/cyberiad.dmm
+++ b/maps/cyberiad.dmm
@@ -5928,11 +5928,11 @@
"cjZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light{dir = 1},/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
"cka" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
"ckb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "mechpod"; name = "Mechanic's Workshop Inner Door"; opacity = 0},/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
-"ckc" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/effect/decal/warning_stripes/east,/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
-"ckd" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/floor{icon_state = "dark"},/area/engine/mechanic_workshop)
-"cke" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/item/stack/sheet/plasteel{amount = 10},/turf/simulated/floor{icon_state = "dark"},/area/engine/mechanic_workshop)
-"ckf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/power/apc{dir = 1; name = "Mechanic Workshop APC"; pixel_y = 24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/item/weapon/circuitboard/mecha/pod,/turf/simulated/floor{icon_state = "dark"},/area/engine/mechanic_workshop)
-"ckg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/item/pod_parts/core,/obj/machinery/camera{c_tag = "Mechanic's Workshop East"; dir = 2; network = list("SS13")},/turf/simulated/floor{icon_state = "dark"},/area/engine/mechanic_workshop)
+"ckc" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/effect/decal/warning_stripes/east,/obj/machinery/spod_part_fabricator,/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
+"ckd" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/engine/mechanic_workshop)
+"cke" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/machinery/computer/rdconsole/mechanics,/turf/simulated/floor{icon_state = "dark"},/area/engine/mechanic_workshop)
+"ckf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/camera{c_tag = "Mechanic's Workshop East"; dir = 2; network = list("SS13")},/turf/simulated/floor{icon_state = "dark"},/area/engine/mechanic_workshop)
+"ckg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/power/apc{dir = 1; name = "Mechanic Workshop APC"; pixel_y = 24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor{icon_state = "dark"},/area/engine/mechanic_workshop)
"ckh" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "dark"},/area/engine/mechanic_workshop)
"cki" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/structure/table/reinforced,/obj/machinery/door/window/westright{name = "Mechanic's Desk"; req_access = null; req_access_txt = "70"; req_one_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
"ckj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 4; icon_state = "yellowcorner"},/area/hallway/primary/aft)
@@ -6043,11 +6043,11 @@
"cmk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
"cml" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
"cmm" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "mechpod"; name = "Mechanic's Workshop Inner Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
-"cmn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/decal/warning_stripes/east,/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
+"cmn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/decal/warning_stripes/east,/obj/machinery/r_n_d/circuit_imprinter,/obj/item/weapon/reagent_containers/glass/beaker/sulphuric,/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
"cmo" = (/obj/machinery/door_control{id = "mechpod"; name = "Mechanic's Inner Door Control"; pixel_x = 0; pixel_y = -24; req_access_txt = "70"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/engine/mechanic_workshop)
-"cmp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/item/stack/rods{amount = 50},/turf/simulated/floor{icon_state = "dark"},/area/engine/mechanic_workshop)
-"cmq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/item/stack/sheet/glass{amount = 50},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor{icon_state = "dark"},/area/engine/mechanic_workshop)
-"cmr" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/item/stack/sheet/metal{amount = 50},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor{icon_state = "dark"},/area/engine/mechanic_workshop)
+"cmp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/item/stack/rods{amount = 50},/obj/structure/table,/obj/item/stack/sheet/plasteel{amount = 10},/turf/simulated/floor{icon_state = "dark"},/area/engine/mechanic_workshop)
+"cmq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/obj/structure/table,/obj/item/pod_parts/core,/obj/item/weapon/circuitboard/mecha/pod,/obj/item/weapon/storage/toolbox/electrical,/turf/simulated/floor{icon_state = "dark"},/area/engine/mechanic_workshop)
+"cmr" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/item/stack/sheet/glass{amount = 50},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/structure/table,/obj/item/stack/sheet/metal{amount = 50},/turf/simulated/floor{icon_state = "dark"},/area/engine/mechanic_workshop)
"cms" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/light_switch{name = "light switch "; dir = 2; pixel_x = 0; pixel_y = -22},/obj/machinery/cell_charger,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = 0; pixel_y = 10},/turf/simulated/floor{icon_state = "dark"},/area/engine/mechanic_workshop)
"cmt" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/engine/mechanic_workshop)
"cmu" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft)
@@ -13287,9 +13287,9 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaacrRcgMcgNcgOcgPcetchYcetcgRcetcgScuPcgUcigcvjaaacxIcnjcyCcobcgZccccccchachbchceOMchdchechfchgcgYchhchichjchkchlckychmcdwcdwcdwchncjWbDgbDgeONeONeOOchoeOPeOReOQeONeOSeOUeOTchveOVeOOeOWcfabXFcfbeKQchwcdMcdNeOqaaaaaaeOgchxchychzeOgbDgbDgbDgeOveOBcgDcgBciMePscgzePtePueQEeQFeQGdNBcwVeBAdNVeOteNceOweOucgCcgCeOyeOxeOzchCchCeOAcuJciOcgCcuIcgCeOXeOXchSeOYeOXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabQZchTchUchVbQZbQZbQXbQXchWbQXbQXbQZbQZaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrRchXcsochZcsociacibcidciccgQcifcoYcjfbWUbWSaaaaaaaaaaaacjpcihciibgnbgncikcilcikcimbYCbTWcineOZcipciqcircircirciscitcdwciucdwcivcjWbDgbDgeONciwcixciycizciAciBeONciAciBcizciCciDciEeOWcghciFcgieKQchwcdMciGeOqeOEeOEeOgeOgeOgeOgeOgciHbDgbDgeOvckUchQchPchQckVchNchNclSclTckWckYcmecmbclVclUciNcpZcnWcnVcsDciXcrzcqachDctrchCchCckScgxckTcgCckPeOXciZcjacjbeOXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaePacjdcjebSjeMMbQZbQZbQXbQYbQXbQZbQZaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOabAcABcABcABcABcABcABcABcABcAIcAIcAIcAIcAIckBcoYcoYcoYcoYcoYcoYcjgeHwcgXcgXcgXcgXcgXcjpcikcikcikcikcikcikcikcjhbYCbTWcjiePbcjkcjlcjmcjncjocAXcjqcjrcjscjtcjucjWbDgbDgeONcjvcjwciycizcizcjxeONcjycizcizciCciycjzeOWeKQeKQeKQePccjAcdMcjBeOqcjCbDgbDgbDgbDgcjDbDgbDgbDgbDgeOvciPeRhchNcjQchNcjPciWchNctuchNchNchNeRbcjIcjGeQYcjKciUeQZeReciYeRgeRfcgKchCchCchCeQWcgxeQIeQIeQIeOXcjScjTcjUeOXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaePdeMJeMJeMLeMMeMMbQZbQZbQZbQZeMNaabaabaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBRcjXcjYcjZckackackbckcckdckeckfckgckhckickjckjckjckkcklckmckncknckockpckqckrcksckrckrckrckqckrckrcktckuckvckwbYCbTWckxePeckzcCccgYcDEcCLcDGcDFcDJcDIcDLcDKcDNbDgbDgeONckCckDckEckFckGckHeONckIckGckJckKckEckLeOWbDgbDgbDgckMchwcdMchwckNbDgbDgbDgbDgbDgbDgbDgbDgbDgbDgeOvckRckXckXckXeQLchNchNeQKckXckXckXckXeQOeQNeOlckQeOmePfeQMeQVclZcmfeQSeQQeQReQQeQPeQHciOeQIeQIeQJeOXckZclaclbeOXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBRcjXcjYcjZckackackbckcckeckdckgckfckhckickjckjckjckkcklckmckncknckockpckqckrcksckrckrckrckqckrckrcktckuckvckwbYCbTWckxePeckzcCccgYcDEcCLcDGcDFcDJcDIcDLcDKcDNbDgbDgeONckCckDckEckFckGckHeONckIckGckJckKckEckLeOWbDgbDgbDgckMchwcdMchwckNbDgbDgbDgbDgbDgbDgbDgbDgbDgbDgeOvckRckXckXckXeQLchNchNeQKckXckXckXckXeQOeQNeOlckQeOmePfeQMeQVclZcmfeQSeQQeQReQQeQPeQHciOeQIeQIeQJeOXckZclaclbeOXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBRcjXclccldclecldclfclgclhclicljclkcllclmclnclnclnclnbYCbTXbTXbTXclncloclnclnclnclnclnclnclnclnclnclnclpclqclrclscltcluePgclwclxcGIclyclzclAclBcHKclDclEclFcHLcficlGePhcjLclIclJclKcizclLeONclHcizclKclMciyclNeOWclOePiePiePjclPclQclReOqePkeOHeOHePleOEeOEeOEeOFeOHeOGeOvciQcmacmacmaciTcmccmdeRFcmaeRGcmacmaciVeOvclWclXclYeOleRDeRxcrAcvGcvFeOIcwWcvFeQTeRHcgxeQIeQIeQIeOXePmcmgePoePnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBRcmicldcmjcmkcmlcmmcmncmocmpcmqcmrcmscmtcmucmvcmwcmwcmxccacmyccacmucmzcmucmucmucmucmucmucmucmucmucmucmAclncmBcmCcmDcmEcHPcmGcmHcmIcmJcmKcmLcmMcmNcmOcmPcmQcDIbXlcmRePpcmTcizciycizcizcmUePqcmVcizcizciCciycmWeOWcmXeOEaaaePreOqcmYeOqeOqaaaaaaaaaaabaabaaaaaaaaaaaaaaaeOveOveOvcgrcvEcgyeOleOleOleOleOleOleOleOleOlcmZcnacnbeOleRseRoeRneQUeQXeRreRqcgCeRdcgCciOeRueRveRteOXePvcnfePvaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBRcmicldcmjcmkcmlcmmcmncmocmpcmrcmqcmscmtcmucmvcmwcmwcmxccacmyccacmucmzcmucmucmucmucmucmucmucmucmucmucmAclncmBcmCcmDcmEcHPcmGcmHcmIcmJcmKcmLcmMcmNcmOcmPcmQcDIbXlcmRePpcmTcizciycizcizcmUePqcmVcizcizciCciycmWeOWcmXeOEaaaePreOqcmYeOqeOqaaaaaaaaaaabaabaaaaaaaaaaaaaaaeOveOveOvcgrcvEcgyeOleOleOleOleOleOleOleOleOlcmZcnacnbeOleRseRoeRneQUeQXeRreRqcgCeRdcgCciOeRueRveRteOXePvcnfePvaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOabAcABcABcABcABcABcABcABcABcABcABcABcABcABcgXcngcolcolcnhcolcnicolcolcIdcIecolcolcIfcIgcIecolcolcolcolcnkcnlcnmcnncnocnpcnqcnrcnscnrcnrcntcnrcnucnvcnwcnxcnycDNbDgcmXePwcnzcnAcnBcnCcnDcnEeONcnFcnDcnGciCcnHcnIeOWcmXeOEaaaePrcnJcnKcnLeOqaaaaaaaaaaaacnMaaaaaaaaaaaaaaaaaaaaaaaacnMaaaaaaeOlcnNcnOcnPePxcnReRlcnTePycnUeRSeRReOleRieRpeRmeRyeRweRweRJeRIclZeRWeRaeQSeRVeRYeOXePAcnYePAaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuacuacuakqakqacuakqakqakqakUakqakqakqakUcnZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacIqcoacIucoccodcoecofcogcohcoicojcokcolcojcomconcoocoocopcolcoqcorcoscotbTWcoucIBcowcoxcoycozcoycoAcoBcoCcoDcoEcoFcDNcDNcmXePweOWeOWcoGeOWeOWePBePDePCePCePCcoHePCePEePCcoIeOEaaaePrcoJcnKcoKeOqePGePFePFePHeOqeOqePJePIePIePKePIePIePKePLaaaaaaeOlcoPcoQcoPcoRcoScoTcoUePyePMcoVePMeOleRzeRBeRAeRAeRCeRweRJeRIeRKcgCciOeRMeRNeRccgqaaacoWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaaaaaaaacuaaaaaaaabaabaaaaabaabaaaaaaaabaabaabaaacnZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacIOcoacIQcoZcpacpbcpccpccpccpccpdcpecpfcoocpgcoocoocphcoocpicpjcpkcplcotbTWcpmePNcpncoxcpocppcpqcoxcprcpscptcpucpvcpwcpxcpycpzcpAcpAcpBcpCcpDcpEcpFbXlbXlbXlcpGbDgbDgbVPbDgeOEaaaePrcpHcnKcpIePOcpJcpKcpLcpMcpNcpOcpPcpNcpOcpQcpNcpRcpSePPaaaaaaeOlcoPcoPcoPePQcpUcnScpVcpWcpXcpYciSeOleRLeRAeRAeRAeROeRweRweRweRTciRcgqcgxcgCcgxcgqaaacqbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
diff --git a/paradise.dme b/paradise.dme
index a8a7f41df4c..ce33dc10412 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -868,6 +868,7 @@
#include "code\game\vehicles\spacepods\construction.dm"
#include "code\game\vehicles\spacepods\equipment.dm"
#include "code\game\vehicles\spacepods\parts.dm"
+#include "code\game\vehicles\spacepods\pod_fabricator.dm"
#include "code\game\vehicles\spacepods\spacepod.dm"
#include "code\game\verbs\atom_verbs.dm"
#include "code\game\verbs\ooc.dm"
@@ -1587,6 +1588,7 @@
#include "code\modules\research\designs\mining_designs.dm"
#include "code\modules\research\designs\misc_designs.dm"
#include "code\modules\research\designs\power_designs.dm"
+#include "code\modules\research\designs\spacepod_designs.dm"
#include "code\modules\research\designs\stock_parts_designs.dm"
#include "code\modules\research\designs\telecomms_designs.dm"
#include "code\modules\research\designs\weapon_designs.dm"