diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index 446715bdac9..9898b6a95e0 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -861,213 +861,6 @@
var/obj/machinery/machine
-///////////////////////////////////////Stock Parts /////////////////////////////////
-
-/obj/item/weapon/stock_parts
- name = "stock part"
- desc = "What?"
- gender = PLURAL
- icon = 'icons/obj/stock_parts.dmi'
- w_class = 2.0
- var/rating = 1
- melt_temperature=MELTPOINT_STEEL
-
-/obj/item/weapon/stock_parts/New()
- . = ..()
- pixel_x = rand(-5, 5)
- pixel_y = rand(-5, 5)
-
-//Rank 1
-
-/obj/item/weapon/stock_parts/console_screen
- name = "console screen"
- desc = "Used in the construction of computers and other devices with a interactive console."
- icon_state = "screen"
- origin_tech = "materials=1"
- starting_materials = list(MAT_GLASS = 200)
- w_type = RECYK_GLASS
-
-/obj/item/weapon/stock_parts/capacitor
- name = "capacitor"
- desc = "A basic capacitor used in the construction of a variety of devices."
- icon_state = "capacitor2_basic"
- origin_tech = "powerstorage=1"
- starting_materials = list(MAT_IRON = 50, MAT_GLASS = 50)
- w_type = RECYK_ELECTRONIC
-
-/obj/item/weapon/stock_parts/scanning_module
- name = "scanning module"
- desc = "A compact, high resolution scanning module used in the construction of certain devices."
- icon_state = "scan_module"
- origin_tech = "magnets=1"
- starting_materials = list(MAT_IRON = 50, MAT_GLASS = 20)
- w_type = RECYK_ELECTRONIC
-
-/obj/item/weapon/stock_parts/manipulator
- name = "micro-manipulator"
- desc = "A tiny little manipulator used in the construction of certain devices."
- icon_state = "micro_mani"
- origin_tech = "materials=1;programming=1"
- starting_materials = list(MAT_IRON = 30)
- w_type = RECYK_ELECTRONIC
-
-/obj/item/weapon/stock_parts/micro_laser
- name = "micro-laser"
- desc = "A tiny laser used in certain devices."
- icon_state = "micro_laser"
- origin_tech = "magnets=1"
- starting_materials = list(MAT_IRON = 10, MAT_GLASS = 20)
- w_type = RECYK_ELECTRONIC
-
-/obj/item/weapon/stock_parts/matter_bin
- name = "matter bin"
- desc = "A container for hold compressed matter awaiting re-construction."
- icon_state = "matter_bin"
- origin_tech = "materials=1"
- starting_materials = list(MAT_IRON = 80)
- w_type = RECYK_ELECTRONIC
-
-//Rank 2
-
-/obj/item/weapon/stock_parts/capacitor/adv
- name = "advanced capacitor"
- desc = "An advanced capacitor used in the construction of a variety of devices."
- icon_state = "capacitor2_adv"
- origin_tech = "powerstorage=3"
- rating = 2
- starting_materials = list(MAT_IRON = 50, MAT_GLASS = 50)
-
-/obj/item/weapon/stock_parts/scanning_module/adv
- name = "advanced scanning module"
- desc = "A compact, high resolution scanning module used in the construction of certain devices."
- icon_state = "scan_module"
- origin_tech = "magnets=3"
- rating = 2
- starting_materials = list(MAT_IRON = 50, MAT_GLASS = 20)
-
-/obj/item/weapon/stock_parts/manipulator/nano
- name = "nano-manipulator"
- desc = "A tiny little manipulator used in the construction of certain devices."
- icon_state = "nano_mani"
- origin_tech = "materials=3;programming=2"
- rating = 2
- starting_materials = list(MAT_IRON = 30)
-
-/obj/item/weapon/stock_parts/micro_laser/high
- name = "high-power micro-laser"
- desc = "A tiny laser used in certain devices."
- icon_state = "high_micro_laser"
- origin_tech = "magnets=3"
- rating = 2
- starting_materials = list(MAT_IRON = 10, MAT_GLASS = 20)
-
-/obj/item/weapon/stock_parts/matter_bin/adv
- name = "advanced matter bin"
- desc = "A container for hold compressed matter awaiting re-construction."
- icon_state = "advanced_matter_bin"
- origin_tech = "materials=3"
- rating = 2
- starting_materials = list(MAT_IRON = 80)
-
-//Rating 3
-
-/obj/item/weapon/stock_parts/capacitor/super
- name = "super capacitor"
- desc = "A super-high capacity capacitor used in the construction of a variety of devices."
- icon_state = "capacitor2_super"
- origin_tech = "powerstorage=5;materials=4"
- rating = 3
- starting_materials = list(MAT_IRON = 50, MAT_GLASS = 50)
-
-/obj/item/weapon/stock_parts/scanning_module/phasic
- name = "phasic scanning module"
- desc = "A compact, high resolution phasic scanning module used in the construction of certain devices."
- origin_tech = "magnets=5"
- rating = 3
- starting_materials = list(MAT_IRON = 50, MAT_GLASS = 20)
-
-/obj/item/weapon/stock_parts/manipulator/pico
- name = "pico-manipulator"
- desc = "A tiny little manipulator used in the construction of certain devices."
- icon_state = "pico_mani"
- origin_tech = "materials=5;programming=2"
- rating = 3
-
-/obj/item/weapon/stock_parts/micro_laser/ultra
- name = "ultra-high-power micro-laser"
- icon_state = "ultra_high_micro_laser"
- desc = "A tiny laser used in certain devices."
- origin_tech = "magnets=5"
- rating = 3
- starting_materials = list(MAT_IRON = 10, MAT_GLASS = 20)
-
-/obj/item/weapon/stock_parts/matter_bin/super
- name = "super matter bin"
- desc = "A container for hold compressed matter awaiting re-construction."
- icon_state = "super_matter_bin"
- origin_tech = "materials=5"
- rating = 3
- starting_materials = list(MAT_IRON = 80)
-
-// Subspace stock parts
-
-/obj/item/weapon/stock_parts/subspace/ansible
- name = "subspace ansible"
- icon_state = "subspace_ansible"
- desc = "A compact module capable of sensing extradimensional activity."
- origin_tech = "programming=3;magnets=5;materials=4;bluespace=2"
- starting_materials = list(MAT_IRON = 30, MAT_GLASS = 10)
-
-/obj/item/weapon/stock_parts/subspace/filter
- name = "hyperwave filter"
- icon_state = "hyperwave_filter"
- desc = "A tiny device capable of filtering and converting super-intense radiowaves."
- origin_tech = "programming=4;magnets=2"
- starting_materials = list(MAT_IRON = 30, MAT_GLASS = 10)
-
-/obj/item/weapon/stock_parts/subspace/amplifier
- name = "subspace amplifier"
- icon_state = "subspace_amplifier"
- desc = "A compact micro-machine capable of amplifying weak subspace transmissions."
- origin_tech = "programming=3;magnets=4;materials=4;bluespace=2"
- starting_materials = list(MAT_IRON = 30, MAT_GLASS = 10)
-
-/obj/item/weapon/stock_parts/subspace/treatment
- name = "subspace treatment disk"
- icon_state = "treatment_disk"
- desc = "A compact micro-machine capable of stretching out hyper-compressed radio waves."
- origin_tech = "programming=3;magnets=2;materials=5;bluespace=2"
- starting_materials = list(MAT_IRON = 30, MAT_GLASS = 10)
-
-/obj/item/weapon/stock_parts/subspace/analyzer
- name = "subspace wavelength analyzer"
- icon_state = "wavelength_analyzer"
- desc = "A sophisticated analyzer capable of analyzing cryptic subspace wavelengths."
- origin_tech = "programming=3;magnets=4;materials=4;bluespace=2"
- starting_materials = list(MAT_IRON = 30, MAT_GLASS = 10)
-
-/obj/item/weapon/stock_parts/subspace/crystal
- name = "ansible crystal"
- icon_state = "ansible_crystal"
- desc = "A crystal made from pure glass used to transmit laser databursts to subspace."
- origin_tech = "magnets=4;materials=4;bluespace=2"
- starting_materials = list(MAT_GLASS = 50)
-
-/obj/item/weapon/stock_parts/subspace/transmitter
- name = "subspace transmitter"
- icon_state = "subspace_transmitter"
- desc = "A large piece of equipment used to open a window into the subspace dimension."
- origin_tech = "magnets=5;materials=5;bluespace=3"
- starting_materials = list(MAT_IRON = 50)
-
-/obj/item/weapon/ectoplasm
- name = "ectoplasm"
- desc = "spooky"
- gender = PLURAL
- icon = 'icons/obj/wizard.dmi'
- icon_state = "ectoplasm"
- w_type = RECYK_BIOLOGICAL
-
/*
/obj/item/weapon/research//Makes testing much less of a pain -Sieve
name = "research"
@@ -1077,6 +870,14 @@
origin_tech = "materials=8;programming=8;magnets=8;powerstorage=8;bluespace=8;combat=8;biotech=8;syndicate=8"
*/
+/obj/item/weapon/ectoplasm
+ name = "ectoplasm"
+ desc = "spooky"
+ gender = PLURAL
+ icon = 'icons/obj/wizard.dmi'
+ icon_state = "ectoplasm"
+ w_type = RECYK_BIOLOGICAL
+
/////////Random shit////////
/obj/item/weapon/lightning
diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm
index ff416cae6a3..de48b149212 100644
--- a/code/game/machinery/constructable_frame.dm
+++ b/code/game/machinery/constructable_frame.dm
@@ -34,7 +34,11 @@
D += "."
desc = D
-/obj/machinery/constructable_frame/machine_frame
+/obj/machinery/constructable_frame/proc/get_req_components_amt()
+ var/amt = 0
+ for(var/path in req_components)
+ amt += req_components[path]
+ return amt
/obj/machinery/constructable_frame/machine_frame/attackby(obj/item/P as obj, mob/user as mob)
if(P.crit_fail)
@@ -153,46 +157,59 @@
components = null
qdel(src)
else
- if(istype(P, /obj/item/weapon)||istype(P, /obj/item/stack))
- for(var/I in req_components)
- if(istype(P, text2path(I)) && (req_components[I] > 0))
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
- if(istype(P, /obj/item/stack/cable_coil))
- var/obj/item/stack/cable_coil/CP = P
- if(CP.amount >= req_components[I])
- var/camt = min(CP.amount, req_components[I]) // amount of cable to take, idealy amount required, but limited by amount provided
- var/obj/item/stack/cable_coil/CC = new /obj/item/stack/cable_coil(src)
- CC.amount = camt
- CC.update_icon()
- CP.use(camt)
- components += CC
- req_components[I] -= camt
- update_desc()
- break
- else
- user << "You do not have enough [P]!"
- if(istype(P, /obj/item/stack/rods))
- var/obj/item/stack/rods/R = P
- if(R.amount >= req_components[I])
- var/camt = min(R.amount, req_components[I]) // amount of cable to take, idealy amount required, but limited by amount provided
- var/obj/item/stack/rods/RR = new /obj/item/stack/rods(src)
- RR.amount = camt
- RR.update_icon()
- R.use(camt)
- components += RR
- req_components[I] -= camt
- update_desc()
- break
- else
- user << "You do not have enough [P]!"
- user.drop_item(P, src)
- components += P
- req_components[I]--
- update_desc()
- break
- user << desc
- if(P && P.loc != src && !istype(P, /obj/item/stack/cable_coil))
- user << "You cannot add that component to the machine!"
+ if(istype(P, /obj/item/weapon/storage/bag/gadgets/part_replacer) && P.contents.len && get_req_components_amt())
+ var/obj/item/weapon/storage/bag/gadgets/part_replacer/replacer = P
+ var/list/added_components = list()
+ var/list/part_list = replacer.contents.Copy()
+
+ //Sort the parts. This ensures that higher tier items are applied first.
+ part_list = sortTim(part_list, /proc/cmp_rped_sort)
+
+ for(var/path in req_components)
+ while(req_components[path] > 0 && (locate(text2path(path)) in part_list))
+ var/obj/item/part = (locate(text2path(path)) in part_list)
+ if(!part.crit_fail)
+ added_components[part] = path
+ replacer.remove_from_storage(part, src)
+ req_components[path]--
+ part_list -= part
+
+ for(var/obj/item/weapon/stock_parts/part in added_components)
+ components += part
+ user << "[part.name] applied."
+ replacer.play_rped_sound()
+
+ update_desc()
+
+ else
+ if(istype(P, /obj/item/weapon) || istype(P, /obj/item/stack))
+ for(var/I in req_components)
+ if(istype(P, text2path(I)) && (req_components[I] > 0))
+ playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ if(istype(P, /obj/item/stack))
+ var/obj/item/stack/CP = P
+ if(CP.amount >= req_components[I])
+ var/camt = min(CP.amount, req_components[I]) // amount of the stack to take, idealy amount required, but limited by amount provided
+ var/obj/item/stack/CC = getFromPool(text2path(I), src)
+ CC.amount = camt
+ CC.update_icon()
+ CP.use(camt)
+ components += CC
+ req_components[I] -= camt
+ update_desc()
+ break
+ else
+ user << "You do not have enough [P]!"
+
+ user.drop_item(P, src)
+ components += P
+ req_components[I]--
+ update_desc()
+ break
+ user << desc
+
+ if(P && P.loc != src && !istype(P, /obj/item/stack/cable_coil))
+ user << "You cannot add that component to the machine!"
/obj/machinery/constructable_frame/machine_frame/proc/set_build_state(var/state)
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/machinery/constructable_frame/machine_frame/proc/set_build_state() called tick#: [world.time]")
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 136db31b33b..7a29eeb7a7b 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -614,6 +614,9 @@ Class Procs:
wirejack(M)
return 1
+ if(istype(O, /obj/item/weapon/storage/bag/gadgets/part_replacer))
+ return exchange_parts(user, O)
+
/obj/machinery/proc/wirejack(var/mob/living/silicon/pai/P)
if(!(machine_flags & WIREJACK))
return 0
@@ -667,4 +670,37 @@ Class Procs:
/obj/machinery/proc/check_rebuild()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/machinery/proc/check_rebuild() called tick#: [world.time]")
- return
\ No newline at end of file
+ return
+
+/obj/machinery/proc/exchange_parts(mob/user, obj/item/weapon/storage/bag/gadgets/part_replacer/W)
+ var/shouldplaysound = 0
+ if(component_parts)
+ if(panel_open)
+ var/obj/item/weapon/circuitboard/CB = locate(/obj/item/weapon/circuitboard) in component_parts
+ var/P
+ for(var/obj/item/A in component_parts)
+ for(var/D in CB.req_components)
+ D = text2path(D) //For some stupid reason these are strings by default.
+ if(ispath(A.type, D))
+ P = D
+ break
+ for(var/obj/item/B in W.contents)
+ if(istype(B, P) && istype(A, P))
+ if(B.get_rating() > A.get_rating())
+ W.remove_from_storage(B, src)
+ W.handle_item_insertion(A, 1)
+ component_parts -= A
+ component_parts += B
+ B.loc = null
+ user << "[A.name] replaced with [B.name]."
+ shouldplaysound = 1 //Only play the sound when parts are actually replaced!
+ break
+ RefreshParts()
+ else
+ user << "Following parts detected in the machine:"
+ for(var/var/obj/item/C in component_parts)
+ user << " [C.name]"
+ if(shouldplaysound)
+ W.play_rped_sound()
+ return 1
+ return 0
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index a7cf5e85c27..d3b6c1ae259 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -843,3 +843,6 @@
step_towards(src,S)
else ..()
+//Gets the rating of the item, used in stuff like machine construction.
+/obj/item/proc/get_rating()
+ return 0
diff --git a/code/game/objects/items/weapons/stock_parts.dm b/code/game/objects/items/weapons/stock_parts.dm
new file mode 100644
index 00000000000..4fee1580a2d
--- /dev/null
+++ b/code/game/objects/items/weapons/stock_parts.dm
@@ -0,0 +1,200 @@
+/obj/item/weapon/stock_parts
+ name = "stock part"
+ desc = "What?"
+ gender = PLURAL
+ icon = 'icons/obj/stock_parts.dmi'
+ w_class = 2.0
+ var/rating = 1
+ melt_temperature = MELTPOINT_STEEL
+
+/obj/item/weapon/stock_parts/New()
+ . = ..()
+ pixel_x = rand(-5, 5)
+ pixel_y = rand(-5, 5)
+
+/obj/item/weapon/stock_parts/get_rating()
+ return rating
+
+//Rank 1
+
+/obj/item/weapon/stock_parts/console_screen
+ name = "console screen"
+ desc = "Used in the construction of computers and other devices with a interactive console."
+ icon_state = "screen"
+ origin_tech = "materials=1"
+ starting_materials = list(MAT_GLASS = 200)
+ w_type = RECYK_GLASS
+
+/obj/item/weapon/stock_parts/capacitor
+ name = "capacitor"
+ desc = "A basic capacitor used in the construction of a variety of devices."
+ icon_state = "capacitor2_basic"
+ origin_tech = "powerstorage=1"
+ starting_materials = list(MAT_IRON = 50, MAT_GLASS = 50)
+ w_type = RECYK_ELECTRONIC
+
+/obj/item/weapon/stock_parts/scanning_module
+ name = "scanning module"
+ desc = "A compact, high resolution scanning module used in the construction of certain devices."
+ icon_state = "scan_module"
+ origin_tech = "magnets=1"
+ starting_materials = list(MAT_IRON = 50, MAT_GLASS = 20)
+ w_type = RECYK_ELECTRONIC
+
+/obj/item/weapon/stock_parts/manipulator
+ name = "micro-manipulator"
+ desc = "A tiny little manipulator used in the construction of certain devices."
+ icon_state = "micro_mani"
+ origin_tech = "materials=1;programming=1"
+ starting_materials = list(MAT_IRON = 30)
+ w_type = RECYK_ELECTRONIC
+
+/obj/item/weapon/stock_parts/micro_laser
+ name = "micro-laser"
+ desc = "A tiny laser used in certain devices."
+ icon_state = "micro_laser"
+ origin_tech = "magnets=1"
+ starting_materials = list(MAT_IRON = 10, MAT_GLASS = 20)
+ w_type = RECYK_ELECTRONIC
+
+/obj/item/weapon/stock_parts/matter_bin
+ name = "matter bin"
+ desc = "A container for hold compressed matter awaiting re-construction."
+ icon_state = "matter_bin"
+ origin_tech = "materials=1"
+ starting_materials = list(MAT_IRON = 80)
+ w_type = RECYK_ELECTRONIC
+
+//Rank 2
+
+/obj/item/weapon/stock_parts/capacitor/adv
+ name = "advanced capacitor"
+ desc = "An advanced capacitor used in the construction of a variety of devices."
+ icon_state = "capacitor2_adv"
+ origin_tech = "powerstorage=3"
+ rating = 2
+ starting_materials = list(MAT_IRON = 50, MAT_GLASS = 50)
+
+/obj/item/weapon/stock_parts/scanning_module/adv
+ name = "advanced scanning module"
+ desc = "A compact, high resolution scanning module used in the construction of certain devices."
+ icon_state = "scan_module"
+ origin_tech = "magnets=3"
+ rating = 2
+ starting_materials = list(MAT_IRON = 50, MAT_GLASS = 20)
+
+/obj/item/weapon/stock_parts/manipulator/nano
+ name = "nano-manipulator"
+ desc = "A tiny little manipulator used in the construction of certain devices."
+ icon_state = "nano_mani"
+ origin_tech = "materials=3;programming=2"
+ rating = 2
+ starting_materials = list(MAT_IRON = 30)
+
+/obj/item/weapon/stock_parts/micro_laser/high
+ name = "high-power micro-laser"
+ desc = "A tiny laser used in certain devices."
+ icon_state = "high_micro_laser"
+ origin_tech = "magnets=3"
+ rating = 2
+ starting_materials = list(MAT_IRON = 10, MAT_GLASS = 20)
+
+/obj/item/weapon/stock_parts/matter_bin/adv
+ name = "advanced matter bin"
+ desc = "A container for hold compressed matter awaiting re-construction."
+ icon_state = "advanced_matter_bin"
+ origin_tech = "materials=3"
+ rating = 2
+ starting_materials = list(MAT_IRON = 80)
+
+//Rating 3
+
+/obj/item/weapon/stock_parts/capacitor/super
+ name = "super capacitor"
+ desc = "A super-high capacity capacitor used in the construction of a variety of devices."
+ icon_state = "capacitor2_super"
+ origin_tech = "powerstorage=5;materials=4"
+ rating = 3
+ starting_materials = list(MAT_IRON = 50, MAT_GLASS = 50)
+
+/obj/item/weapon/stock_parts/scanning_module/phasic
+ name = "phasic scanning module"
+ desc = "A compact, high resolution phasic scanning module used in the construction of certain devices."
+ origin_tech = "magnets=5"
+ rating = 3
+ starting_materials = list(MAT_IRON = 50, MAT_GLASS = 20)
+
+/obj/item/weapon/stock_parts/manipulator/pico
+ name = "pico-manipulator"
+ desc = "A tiny little manipulator used in the construction of certain devices."
+ icon_state = "pico_mani"
+ origin_tech = "materials=5;programming=2"
+ rating = 3
+ starting_materials = list(MAT_IRON = 30)
+
+/obj/item/weapon/stock_parts/micro_laser/ultra
+ name = "ultra-high-power micro-laser"
+ icon_state = "ultra_high_micro_laser"
+ desc = "A tiny laser used in certain devices."
+ origin_tech = "magnets=5"
+ rating = 3
+ starting_materials = list(MAT_IRON = 10, MAT_GLASS = 20)
+
+/obj/item/weapon/stock_parts/matter_bin/super
+ name = "super matter bin"
+ desc = "A container for hold compressed matter awaiting re-construction."
+ icon_state = "super_matter_bin"
+ origin_tech = "materials=5"
+ rating = 3
+ starting_materials = list(MAT_IRON = 80)
+
+// Subspace stock parts
+
+/obj/item/weapon/stock_parts/subspace/ansible
+ name = "subspace ansible"
+ icon_state = "subspace_ansible"
+ desc = "A compact module capable of sensing extradimensional activity."
+ origin_tech = "programming=3;magnets=5;materials=4;bluespace=2"
+ starting_materials = list(MAT_IRON = 30, MAT_GLASS = 10)
+
+/obj/item/weapon/stock_parts/subspace/filter
+ name = "hyperwave filter"
+ icon_state = "hyperwave_filter"
+ desc = "A tiny device capable of filtering and converting super-intense radiowaves."
+ origin_tech = "programming=4;magnets=2"
+ starting_materials = list(MAT_IRON = 30, MAT_GLASS = 10)
+
+/obj/item/weapon/stock_parts/subspace/amplifier
+ name = "subspace amplifier"
+ icon_state = "subspace_amplifier"
+ desc = "A compact micro-machine capable of amplifying weak subspace transmissions."
+ origin_tech = "programming=3;magnets=4;materials=4;bluespace=2"
+ starting_materials = list(MAT_IRON = 30, MAT_GLASS = 10)
+
+/obj/item/weapon/stock_parts/subspace/treatment
+ name = "subspace treatment disk"
+ icon_state = "treatment_disk"
+ desc = "A compact micro-machine capable of stretching out hyper-compressed radio waves."
+ origin_tech = "programming=3;magnets=2;materials=5;bluespace=2"
+ starting_materials = list(MAT_IRON = 30, MAT_GLASS = 10)
+
+/obj/item/weapon/stock_parts/subspace/analyzer
+ name = "subspace wavelength analyzer"
+ icon_state = "wavelength_analyzer"
+ desc = "A sophisticated analyzer capable of analyzing cryptic subspace wavelengths."
+ origin_tech = "programming=3;magnets=4;materials=4;bluespace=2"
+ starting_materials = list(MAT_IRON = 30, MAT_GLASS = 10)
+
+/obj/item/weapon/stock_parts/subspace/crystal
+ name = "ansible crystal"
+ icon_state = "ansible_crystal"
+ desc = "A crystal made from pure glass used to transmit laser databursts to subspace."
+ origin_tech = "magnets=4;materials=4;bluespace=2"
+ starting_materials = list(MAT_GLASS = 50)
+
+/obj/item/weapon/stock_parts/subspace/transmitter
+ name = "subspace transmitter"
+ icon_state = "subspace_transmitter"
+ desc = "A large piece of equipment used to open a window into the subspace dimension."
+ origin_tech = "magnets=5;materials=5;bluespace=3"
+ starting_materials = list(MAT_IRON = 50)
diff --git a/code/game/objects/items/weapons/storage/RPED.dm b/code/game/objects/items/weapons/storage/RPED.dm
new file mode 100644
index 00000000000..c62ef0eb41f
--- /dev/null
+++ b/code/game/objects/items/weapons/storage/RPED.dm
@@ -0,0 +1,35 @@
+/obj/item/weapon/storage/bag/gadgets/part_replacer //Bag because disposals bin snowflake code is shit
+ name = "rapid part exchange device"
+ desc = "Special mechanical module made to store, sort, and apply standard machine parts."
+ icon_state = "RPED"
+ item_state = "RPED"
+ w_class = 5
+ use_to_pickup = 1
+ max_w_class = 3
+ max_combined_w_class = 100
+ storage_slots = 50
+ inhand_states = list("left_hand" = 'icons/mob/in-hand/left/misc_tools.dmi', "right_hand" = 'icons/mob/in-hand/right/misc_tools.dmi')
+
+/obj/item/weapon/storage/bag/gadgets/part_replacer/proc/play_rped_sound()
+ //Plays the sound for RPED exhanging or installing parts.
+ playsound(src, 'sound/items/rped.ogg', 40, 1)
+
+//Sorts items by their rating. Currently used by the RPED (did that need mentioning since this proc is in RPED.dm?)
+//Only use /obj/item with this sort proc!
+/proc/cmp_rped_sort(var/obj/item/A, var/obj/item/B)
+ return B.get_rating() - A.get_rating()
+
+/obj/item/weapon/storage/bag/gadgets/part_replacer/attackby(var/obj/item/weapon/W, var/mob/user)
+ if(istype(W, /obj/item/weapon/storage/bag/gadgets)) //I guess this allows for moving stuff between RPEDs, honk.
+ var/obj/item/weapon/storage/bag/gadgets/A = W
+ if(A.contents.len <= 0)
+ user << "\the [A] is empty!"
+ return 1
+ if(src.contents.len >= storage_slots)
+ user << "\the [src] is full!"
+ return 1
+ A.mass_remove(src)
+ user << "You fill up \the [src] with \the [A]"
+ return 1
+
+ return ..()
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm
index 3a3dfd3dbfb..bc465779534 100644
--- a/code/game/objects/items/weapons/storage/bags.dm
+++ b/code/game/objects/items/weapons/storage/bags.dm
@@ -292,4 +292,15 @@
max_combined_w_class = 200
max_w_class = 3
w_class = 1
- can_hold = list("/obj/item/weapon/stock_parts")
\ No newline at end of file
+ can_hold = list("/obj/item/weapon/stock_parts", "/obj/item/weapon/reagent_containers/glass/beaker", "/obj/item/weapon/cell")
+
+/obj/item/weapon/storage/bag/gadgets/mass_remove(atom/A)
+ var/lowest_rating = INFINITY //Get the lowest rating, so only mass drop the lowest parts.
+ for(var/obj/item/B in contents)
+ if(B.get_rating() < lowest_rating)
+ lowest_rating = B.get_rating()
+
+ for(var/obj/item/B in contents) //Now that we have the lowest rating we can dump only parts at the lowest rating.
+ if(B.get_rating() > lowest_rating)
+ continue
+ remove_from_storage(B, A)
diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm
index 3bf9fd60a7b..2f10fefd5db 100644
--- a/code/game/objects/items/weapons/storage/storage.dm
+++ b/code/game/objects/items/weapons/storage/storage.dm
@@ -285,7 +285,7 @@
if(usr)
usr.u_equip(W,1)
usr.update_icons() //update our overlays
- W.loc = src
+ W.forceMove(src)
W.on_enter_storage(src)
if(usr)
if (usr.client && usr.s_active != src)
@@ -309,10 +309,16 @@
return 1
//Call this proc to handle the removal of an item from the storage item. The item will be moved to the atom sent as new_target
-/obj/item/weapon/storage/proc/remove_from_storage(obj/item/W as obj, atom/new_location)
+//force needs to be 1 if you want to override the can_be_inserted() if the target's a storage item.
+/obj/item/weapon/storage/proc/remove_from_storage(obj/item/W as obj, atom/new_location, var/force = 0)
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/item/weapon/storage/proc/remove_from_storage() called tick#: [world.time]")
if(!istype(W)) return 0
+ if(!force && istype(new_location, /obj/item/weapon/storage))
+ var/obj/item/weapon/storage/A = new_location
+ if(!A.can_be_inserted(W, 1))
+ return 0
+
if(istype(src, /obj/item/weapon/storage/fancy))
var/obj/item/weapon/storage/fancy/F = src
F.update_icon(1)
@@ -332,9 +338,13 @@
W.pickup(M)
M.put_in_active_hand(W)
else
- W.loc = new_location
+ if(istype(new_location, /obj/item/weapon/storage))
+ var/obj/item/weapon/storage/A = new_location
+ A.handle_item_insertion(W, 1)
+ else
+ W.forceMove(new_location)
else
- W.loc = get_turf(src)
+ W.forceMove(get_turf(src))
if(usr)
src.orient2hud(usr)
@@ -456,8 +466,7 @@
var/turf/T = get_turf(src)
hide_from(usr)
- for(var/obj/item/I in contents)
- remove_from_storage(I, T)
+ mass_remove(T)
/obj/item/weapon/storage/New()
. = ..()
@@ -602,4 +611,8 @@
/obj/item/weapon/storage/stripped(mob/wearer as mob, mob/stripper as mob)
for(var/obj/item/I in contents)
- I.stripped(wearer,stripper)
\ No newline at end of file
+ I.stripped(wearer,stripper)
+
+/obj/item/weapon/storage/proc/mass_remove(var/atom/A)
+ for(var/obj/item/O in contents)
+ remove_from_storage(O, A)
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index 9cc86c22bf2..1c351e4c45e 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -158,3 +158,6 @@
return round(charge**(1/3)*(rand(100,125)/100)) //Cube root of power times 1,5 to 2 in increments of 10^-1
//For instance, gives an average of 81 damage for 100k W and 175 for 1M W
//Best you're getting with BYOND's mathematical funcs. Not even a fucking exponential or neperian logarithm
+
+/obj/item/weapon/cell/get_rating()
+ return maxcharge / 10000
diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm
index fa09335e06d..c7d42828fe7 100644
--- a/code/modules/reagents/reagent_containers/glass.dm
+++ b/code/modules/reagents/reagent_containers/glass.dm
@@ -50,6 +50,9 @@
/obj/machinery/bunsen_burner
)
+/obj/item/weapon/reagent_containers/glass/get_rating()
+ return volume / 50
+
/obj/item/weapon/reagent_containers/glass/New()
..()
base_name = name
diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm
index 36057fab091..991dcfbb1ba 100644
--- a/code/modules/recycling/disposal.dm
+++ b/code/modules/recycling/disposal.dm
@@ -128,8 +128,7 @@
user.drop_item(I, src)
return
user << " You empty the [B]."
- for(var/obj/item/O in B.contents)
- B.remove_from_storage(O,src)
+ B.mass_remove(src)
B.update_icon()
update_icon()
return
diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm
index 4191c9dafc4..07e4ef5364b 100644
--- a/code/modules/research/designs.dm
+++ b/code/modules/research/designs.dm
@@ -1,4 +1,4 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
+ //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
/***************************************************************
** Design Datums **
diff --git a/code/modules/research/designs/engineering.dm b/code/modules/research/designs/engineering.dm
index 1f6c3367911..8e4a9629f62 100644
--- a/code/modules/research/designs/engineering.dm
+++ b/code/modules/research/designs/engineering.dm
@@ -80,7 +80,8 @@
category = "Engineering"
build_path = /obj/item/device/device_analyser
-//Sadly there is not file "trash.dm"
+//Sadly there is no file "trash.dm"
+/*
/datum/design/component_exchanger
name = "Rapid Machinery Component Exchanger"
desc = "A device that allows to quickly replace machinery components, useful for upgrading."
@@ -90,3 +91,14 @@
materials = list(MAT_IRON = 500, MAT_GLASS = 1000, MAT_GOLD = 200, MAT_SILVER = 200)
category = "Engineering"
build_path = /obj/item/weapon/storage/component_exchanger
+*/
+
+/datum/design/RPED
+ name = "Rapid Part Exchange Device"
+ desc = "Special mechanical module made to store, sort, and apply standard machine parts."
+ id = "rped"
+ req_tech = list("engineering" = 4, "materials" = 4, "programming" = 2)
+ build_type = PROTOLATHE
+ materials = list(MAT_IRON = 500, MAT_GLASS = 1000, MAT_GOLD = 200, MAT_SILVER = 200)
+ build_path = /obj/item/weapon/storage/bag/gadgets/part_replacer
+ category = "Engineering"
diff --git a/html/changelogs/PJB3005-RPED.yml b/html/changelogs/PJB3005-RPED.yml
new file mode 100644
index 00000000000..ba6521b5cbf
--- /dev/null
+++ b/html/changelogs/PJB3005-RPED.yml
@@ -0,0 +1,14 @@
+delete-after: true
+author: PJB3005
+changes:
+ - rscdel: Removed dylan's Rapid Machine Component Exchanger (RMCE).
+ - rscadd: Ported the Rapid Part Exchangement Device (RPED) from /tg/, to replace the RMCE.
+ - tweak: The RPED has no delay.
+ - tweak: The RPED can be emptied into disposals bins.
+ - tweak: Mass removing items from the RPED will drop the lowest tier items first.
+ - tweak: The RPED can be used in construction of machines.
+ - tweak: Using the RPED on a machine with an open panel will replace parts, with a closed panel, will output a list of parts.
+ - soundadd: Super fancy RPED sounds.
+ - bugfix: The RPED does not have a couple of RMCE bugs (UI ghosting, dumb assumptions).
+ - tweak: The RPED does NOT fit in backpacks.
+ - tweak: The RPED can replace beakers in machines.
\ No newline at end of file
diff --git a/icons/mob/in-hand/left/misc_tools.dmi b/icons/mob/in-hand/left/misc_tools.dmi
index 6895892e2e2..c8f26ef91e6 100644
Binary files a/icons/mob/in-hand/left/misc_tools.dmi and b/icons/mob/in-hand/left/misc_tools.dmi differ
diff --git a/icons/mob/in-hand/right/misc_tools.dmi b/icons/mob/in-hand/right/misc_tools.dmi
index 8e6383e0038..102666f9a41 100644
Binary files a/icons/mob/in-hand/right/misc_tools.dmi and b/icons/mob/in-hand/right/misc_tools.dmi differ
diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi
index fb6f5bf1b1f..b4363d16a53 100644
Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ
diff --git a/sound/items/rped.ogg b/sound/items/rped.ogg
new file mode 100644
index 00000000000..93dca60d341
Binary files /dev/null and b/sound/items/rped.ogg differ
diff --git a/vgstation13.dme b/vgstation13.dme
index db53ed6c14b..1368c271fbc 100644
--- a/vgstation13.dme
+++ b/vgstation13.dme
@@ -684,6 +684,7 @@
#include "code\game\objects\items\weapons\scrolls.dm"
#include "code\game\objects\items\weapons\shard.dm"
#include "code\game\objects\items\weapons\shields.dm"
+#include "code\game\objects\items\weapons\stock_parts.dm"
#include "code\game\objects\items\weapons\stunbaton.dm"
#include "code\game\objects\items\weapons\surgery_tools.dm"
#include "code\game\objects\items\weapons\switchtool.dm"
@@ -728,6 +729,7 @@
#include "code\game\objects\items\weapons\storage\fancy.dm"
#include "code\game\objects\items\weapons\storage\firstaid.dm"
#include "code\game\objects\items\weapons\storage\lockbox.dm"
+#include "code\game\objects\items\weapons\storage\RPED.dm"
#include "code\game\objects\items\weapons\storage\secure.dm"
#include "code\game\objects\items\weapons\storage\storage.dm"
#include "code\game\objects\items\weapons\storage\toolbox.dm"