diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm
index 60f331a592..76709d438e 100644
--- a/code/game/machinery/_machinery.dm
+++ b/code/game/machinery/_machinery.dm
@@ -401,19 +401,28 @@ Class Procs:
var/P
if(W.works_from_distance)
display_parts(user)
- for(var/obj/item/stock_parts/A in component_parts)
+ for(var/obj/item/A in component_parts)
for(var/D in CB.req_components)
if(ispath(A.type, D))
P = D
break
- for(var/obj/item/stock_parts/B in W.contents)
+ for(var/obj/item/B in W.contents)
if(istype(B, P) && istype(A, P))
- if(B.rating > A.rating)
- W.remove_from_storage(B, src)
+ if(B.get_part_rating() > A.get_part_rating())
+ if(istype(B,/obj/item/stack)) //conveniently this will mean A is also a stack and I will kill the first person to prove me wrong
+ var/obj/item/stack/SA = A
+ var/obj/item/stack/SB = B
+ var/used_amt = SA.get_amount()
+ if(!SB.use(used_amt))
+ continue //if we don't have the exact amount to replace we don't
+ var/obj/item/stack/SN = new SB.merge_type(null,used_amt)
+ component_parts += SN
+ else
+ W.remove_from_storage(B, src)
+ component_parts += B
+ B.moveToNullspace()
W.handle_item_insertion(A, 1)
component_parts -= A
- component_parts += B
- B.moveToNullspace()
to_chat(user, "[A.name] replaced with [B.name].")
shouldplaysound = 1 //Only play the sound when parts are actually replaced!
break
diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm
index 6c9b8e3a0d..b95bf7d663 100644
--- a/code/game/machinery/constructable_frame.dm
+++ b/code/game/machinery/constructable_frame.dm
@@ -192,7 +192,7 @@
var/list/part_list = list()
//Assemble a list of current parts, then sort them by their rating!
- for(var/obj/item/stock_parts/co in replacer)
+ for(var/obj/item/co in replacer)
part_list += co
//Sort the parts. This ensures that higher tier items are applied first.
part_list = sortTim(part_list, /proc/cmp_rped_sort)
@@ -200,13 +200,28 @@
for(var/path in req_components)
while(req_components[path] > 0 && (locate(path) in part_list))
var/obj/item/part = (locate(path) in part_list)
- added_components[part] = path
- replacer.remove_from_storage(part, src)
- req_components[path]--
part_list -= part
+ if(istype(part,/obj/item/stack))
+ var/obj/item/stack/S = part
+ var/used_amt = min(round(S.get_amount()), req_components[path])
+ if(!used_amt || !S.use(used_amt))
+ continue
+ var/NS = new S.merge_type(src, used_amt)
+ added_components[NS] = path
+ req_components[path] -= used_amt
+ else
+ added_components[part] = path
+ replacer.remove_from_storage(part, src)
+ req_components[path]--
- for(var/obj/item/stock_parts/part in added_components)
- components += part
+ for(var/obj/item/part in added_components)
+ if(istype(part,/obj/item/stack))
+ var/obj/item/stack/S = part
+ var/obj/item/stack/NS = locate(S.merge_type) in components //find a stack to merge with
+ if(NS)
+ S.merge(NS)
+ if(!QDELETED(part)) //If we're a stack and we merged we might not exist anymore
+ components += part
to_chat(user, "[part.name] applied.")
if(added_components.len)
replacer.play_rped_sound()
@@ -242,7 +257,6 @@
if(user.a_intent == INTENT_HARM)
return ..()
-
/obj/structure/frame/machine/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(state >= 2)
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 697c84ee0c..9d3814c145 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -817,3 +817,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
// Used in a callback that is passed by use_tool into do_after call. Do not override, do not call manually.
/obj/item/proc/tool_check_callback(mob/living/user, amount, datum/callback/extra_checks)
return tool_use_check(user, amount) && (!extra_checks || extra_checks.Invoke())
+
+// Returns a numeric value for sorting items used as parts in machines, so they can be replaced by the rped
+/obj/item/proc/get_part_rating()
+ return 0
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/bscrystal.dm b/code/game/objects/items/stacks/bscrystal.dm
index f4b5ec9efe..d4dc971db9 100644
--- a/code/game/objects/items/stacks/bscrystal.dm
+++ b/code/game/objects/items/stacks/bscrystal.dm
@@ -21,6 +21,9 @@
pixel_x = rand(-5, 5)
pixel_y = rand(-5, 5)
+/obj/item/stack/ore/bluespace_crystal/get_part_rating()
+ return 1
+
/obj/item/stack/ore/bluespace_crystal/attack_self(mob/user)
user.visible_message("[user] crushes [src]!", "You crush [src]!")
new /obj/effect/particle_effect/sparks(loc)
diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm
index 7e0aa59816..78a749033a 100644
--- a/code/modules/assembly/assembly.dm
+++ b/code/modules/assembly/assembly.dm
@@ -25,6 +25,9 @@
var/next_activate = 0 //When we're next allowed to activate - for spam control
+/obj/item/device/assembly/get_part_rating()
+ return 1
+
/obj/item/device/assembly/proc/on_attach()
/obj/item/device/assembly/proc/on_detach()
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index c6d3e13359..498b9e608b 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -157,6 +157,9 @@
else
return 0
+/obj/item/stock_parts/cell/get_part_rating()
+ return rating * maxcharge
+
/* Cell variants*/
/obj/item/stock_parts/cell/empty/Initialize()
. = ..()
@@ -167,7 +170,6 @@
desc = "You can't top the plasma top." //TOTALLY TRADEMARK INFRINGEMENT
maxcharge = 500
materials = list(MAT_GLASS=40)
- rating = 2
/obj/item/stock_parts/cell/crap/empty/Initialize()
. = ..()
@@ -179,7 +181,6 @@
desc = "A power cell with a slightly higher capacity than normal!"
maxcharge = 2500
materials = list(MAT_GLASS=50)
- rating = 2
chargerate = 1000
/obj/item/stock_parts/cell/upgraded/plus
@@ -191,7 +192,6 @@
name = "security borg rechargeable D battery"
maxcharge = 600 //600 max charge / 100 charge per shot = six shots
materials = list(MAT_GLASS=40)
- rating = 2.5
/obj/item/stock_parts/cell/secborg/empty/Initialize()
. = ..()
@@ -201,7 +201,6 @@
/obj/item/stock_parts/cell/pulse //200 pulse shots
name = "pulse rifle power cell"
maxcharge = 40000
- rating = 3
chargerate = 1500
/obj/item/stock_parts/cell/pulse/carbine //25 pulse shots
@@ -217,7 +216,6 @@
icon_state = "hcell"
maxcharge = 10000
materials = list(MAT_GLASS=60)
- rating = 3
chargerate = 1500
/obj/item/stock_parts/cell/high/plus
@@ -237,7 +235,6 @@
icon_state = "scell"
maxcharge = 20000
materials = list(MAT_GLASS=300)
- rating = 4
chargerate = 2000
/obj/item/stock_parts/cell/super/empty/Initialize()
@@ -250,7 +247,6 @@
icon_state = "hpcell"
maxcharge = 30000
materials = list(MAT_GLASS=400)
- rating = 5
chargerate = 3000
/obj/item/stock_parts/cell/hyper/empty/Initialize()
@@ -264,7 +260,6 @@
icon_state = "bscell"
maxcharge = 40000
materials = list(MAT_GLASS=600)
- rating = 6
chargerate = 4000
/obj/item/stock_parts/cell/bluespace/empty/Initialize()
@@ -277,7 +272,7 @@
icon_state = "icell"
maxcharge = 30000
materials = list(MAT_GLASS=1000)
- rating = 6
+ rating = 100
chargerate = 30000
/obj/item/stock_parts/cell/infinite/use()
@@ -289,7 +284,6 @@
icon = 'icons/obj/abductor.dmi'
icon_state = "cell"
maxcharge = 50000
- rating = 12
ratingdesc = FALSE
/obj/item/stock_parts/cell/infinite/abductor/update_icon()
@@ -304,7 +298,6 @@
charge = 100
maxcharge = 300
materials = list()
- rating = 1
grown_battery = TRUE //it has the overlays for wires
/obj/item/stock_parts/cell/high/slime
@@ -313,13 +306,14 @@
icon = 'icons/mob/slimes.dmi'
icon_state = "yellow slime extract"
materials = list()
+ rating = 5 //self-recharge makes these desirable
self_recharge = 1 // Infused slime cores self-recharge, over time
/obj/item/stock_parts/cell/emproof
name = "\improper EMP-proof cell"
desc = "An EMP-proof cell."
maxcharge = 500
- rating = 2
+ rating = 3
/obj/item/stock_parts/cell/emproof/empty/Initialize()
. = ..()
@@ -337,7 +331,6 @@
desc = "A high powered capacitor that can provide huge amounts of energy in an instant."
maxcharge = 50000
chargerate = 5000 //Extremely energy intensive
- rating = 4
/obj/item/stock_parts/cell/beam_rifle/corrupt()
return
@@ -350,7 +343,6 @@
desc = "A tiny power cell with a very low power capacity. Used in light fixtures to power them in the event of an outage."
maxcharge = 120 //Emergency lights use 0.2 W per tick, meaning ~10 minutes of emergency power from a cell
materials = list(MAT_GLASS = 20)
- rating = 1
w_class = WEIGHT_CLASS_TINY
/obj/item/stock_parts/cell/emergency_light/Initialize()
diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm
index f8a01b16f0..e337953f33 100644
--- a/code/modules/reagents/reagent_containers/glass.dm
+++ b/code/modules/reagents/reagent_containers/glass.dm
@@ -118,6 +118,9 @@
. = ..()
update_icon()
+/obj/item/reagent_containers/glass/beaker/get_part_rating()
+ return reagents.maximum_volume
+
/obj/item/reagent_containers/glass/beaker/on_reagent_change(changetype)
update_icon()
diff --git a/code/modules/research/stock_parts.dm b/code/modules/research/stock_parts.dm
index 7c247d0b67..d00b5e3137 100644
--- a/code/modules/research/stock_parts.dm
+++ b/code/modules/research/stock_parts.dm
@@ -9,7 +9,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
w_class = WEIGHT_CLASS_HUGE
- can_hold = list(/obj/item/stock_parts)
storage_slots = 50
use_to_pickup = 1
allow_quick_gather = 1
@@ -22,6 +21,9 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi
var/pshoom_or_beepboopblorpzingshadashwoosh = 'sound/items/rped.ogg'
var/alt_sound = null
+/obj/item/storage/part_replacer/can_be_inserted(obj/item/W, stop_messages = 0, mob/user)
+ return ..() && W.get_part_rating()
+
/obj/item/storage/part_replacer/afterattack(obj/machinery/T, mob/living/carbon/human/user, flag, params)
if(flag)
return
@@ -72,9 +74,8 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
//Sorts stock parts inside an RPED by their rating.
-//Only use /obj/item/stock_parts/ with this sort proc!
-/proc/cmp_rped_sort(obj/item/stock_parts/A, obj/item/stock_parts/B)
- return B.rating - A.rating
+/proc/cmp_rped_sort(obj/item/A, obj/item/B)
+ return A.get_part_rating() - B.get_part_rating()
/obj/item/stock_parts
name = "stock part"
@@ -88,6 +89,8 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi
pixel_x = rand(-5, 5)
pixel_y = rand(-5, 5)
+/obj/item/stock_parts/get_part_rating()
+ return rating
//Rating 1
/obj/item/stock_parts/capacitor