diff --git a/code/_globalvars/lists/construction.dm b/code/_globalvars/lists/construction.dm
new file mode 100644
index 00000000000..3accb854ca1
--- /dev/null
+++ b/code/_globalvars/lists/construction.dm
@@ -0,0 +1,18 @@
+///A cache with all the objects craftable with a plumbing constructor and their delay (doubles as their cost, 1sec/10 matter)
+GLOBAL_LIST_INIT(plumbing_constructables, list(
+ /obj/machinery/plumbing/input = 5,
+ /obj/machinery/plumbing/output = 5,
+ /obj/machinery/plumbing/tank = 20,
+ /obj/machinery/plumbing/acclimator = 10,
+ /obj/machinery/plumbing/bottler = 50,
+ /obj/machinery/plumbing/disposer = 10,
+ /obj/machinery/plumbing/fermenter = 30,
+ /obj/machinery/plumbing/filter = 5,
+ /obj/machinery/plumbing/grinder_chemical = 30,
+ /obj/machinery/plumbing/pill_press = 20,
+ /obj/machinery/plumbing/liquid_pump = 35,
+ /obj/machinery/plumbing/reaction_chamber = 15,
+ /obj/machinery/plumbing/splitter = 5,
+ /obj/machinery/plumbing/synthesizer = 15,
+ /obj/machinery/plumbing/sender = 20
+))
diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm
index 0c4d6aed90a..a600888fd8f 100644
--- a/code/game/objects/items/RCD.dm
+++ b/code/game/objects/items/RCD.dm
@@ -906,6 +906,7 @@ RLD
max_matter = 100
matter_divisor = 20
+///The plumbing RCD. All the blueprints are located in _globalvars > lists > construction.dm
/obj/item/construction/plumbing
name = "Plumbing Constructor"
desc = "An expertly modified RCD outfitted to construct plumbing machinery."
@@ -922,19 +923,18 @@ RLD
var/list/choices = list()
///index, used in the attack self to get the type. stored here since it doesnt change
var/list/name_to_type = list()
- ///
- var/list/machinery_data = list("cost" = list(), "delay" = list())
+ ///All info for construction
+ var/list/machinery_data = list("cost" = list())
/obj/item/construction/plumbing/attack_self(mob/user)
..()
if(!choices.len)
- for(var/A in subtypesof(/obj/machinery/plumbing))
+ for(var/A in GLOB.plumbing_constructables)
var/obj/machinery/plumbing/M = A
- if(initial(M.rcd_constructable))
- choices += list(initial(M.name) = image(icon = initial(M.icon), icon_state = initial(M.icon_state)))
- name_to_type[initial(M.name)] = M
- machinery_data["cost"][A] = initial(M.rcd_cost)
- machinery_data["delay"][A] = initial(M.rcd_delay)
+
+ choices += list(initial(M.name) = image(icon = initial(M.icon), icon_state = initial(M.icon_state)))
+ name_to_type[initial(M.name)] = M
+ machinery_data["cost"][A] = GLOB.plumbing_constructables[A]
var/choice = show_radial_menu(user, src, choices, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
if(!check_menu(user))
@@ -950,7 +950,8 @@ RLD
return FALSE
if(checkResource(machinery_data["cost"][blueprint], user) && blueprint)
- if(do_after(user, machinery_data["delay"][blueprint], target = A))
+ //"cost" is relative to delay at a rate of 10 matter/second (1matter/decisecond) rather than playing with 2 different variables since everyone set it to this rate anyways.
+ if(do_after(user, machinery_data["cost"][blueprint], target = A))
if(checkResource(machinery_data["cost"][blueprint], user) && canPlace(A))
useResource(machinery_data["cost"][blueprint], user)
activate()
diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm
index 5f52cb203c7..bb941a1cf03 100644
--- a/code/game/objects/items/circuitboards/machine_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm
@@ -1198,6 +1198,17 @@
/obj/item/stock_parts/scanning_module = 2
)
+/obj/item/circuitboard/machine/plumbing_receiver
+ name = "Chemical Recipient (Machine Board)"
+ icon_state = "medical"
+ build_path = /obj/machinery/plumbing/receiver
+ req_components = list(
+ /obj/item/stack/ore/bluespace_crystal = 1,
+ /obj/item/stock_parts/capacitor = 2,
+ /obj/item/stack/sheet/glass = 1)
+ def_components = list(/obj/item/stack/ore/bluespace_crystal = /obj/item/stack/ore/bluespace_crystal/artificial)
+ needs_anchored = FALSE
+
/obj/item/circuitboard/machine/skill_station
name = "Skill Station (Machine Board)"
build_path = /obj/machinery/skill_station
@@ -1206,3 +1217,4 @@
/obj/item/stock_parts/micro_laser = 2,
/obj/item/stock_parts/scanning_module = 2
)
+
diff --git a/code/modules/plumbing/plumbers/_plumb_machinery.dm b/code/modules/plumbing/plumbers/_plumb_machinery.dm
index 19bc21239ac..293d32fd742 100644
--- a/code/modules/plumbing/plumbers/_plumb_machinery.dm
+++ b/code/modules/plumbing/plumbers/_plumb_machinery.dm
@@ -16,11 +16,6 @@
///Flags for reagents, like INJECTABLE, TRANSPARENT bla bla everything thats in DEFINES/reagents.dm
var/reagent_flags = TRANSPARENT
///wheter we partake in rcd construction or not
- var/rcd_constructable = TRUE
- ///cost of the plumbing rcd construction
- var/rcd_cost = 15
- ///delay of constructing it throught the plumbing rcd
- var/rcd_delay = 10
/obj/machinery/plumbing/Initialize(mapload, bolt = TRUE)
. = ..()
@@ -53,7 +48,7 @@
to_chat(user, "The [name] needs to be unbolted to do that!You start slicing the [name] apart.You slice the [name] apart.Invalid buffer.")
+ return
+
+ if(target)
+ lose_teleport_target()
+
+ set_teleport_target(M.buffer)
+
+ to_chat(user, "You succesfully link [src] to the [M.buffer].")
+ return TRUE
+
+///Lose our previous target and make our previous target lose us. Seperate proc because I feel like I'll need this again
+/obj/machinery/plumbing/sender/proc/lose_teleport_target()
+ target.senders.Remove(src)
+ target = null
+ icon_state = initial(icon_state)
+
+///Set a receiving plumbing object
+/obj/machinery/plumbing/sender/proc/set_teleport_target(new_target)
+ target = new_target
+ target.senders.Add(src)
+ icon_state = initial(icon_state) + "_idle"
+
+///Transfer reagents and display a flashing icon
+/obj/machinery/plumbing/sender/proc/teleport_chemicals(obj/machinery/plumbing/receiver/R, amount)
+ flick(initial(icon_state) + "_flash", src)
+ reagents.trans_to(R, amount, round_robin = TRUE)
+
+///A bluespace output pipe for plumbing. Supports multiple recipients. Must be constructed with a circuit board
+/obj/machinery/plumbing/receiver
+ name = "chemical recipient"
+ desc = "Receives chemicals from one or more chemical beacons. Use a multitool on this machine and then all subsequent chemical beacons. Reset by opening the \
+ panel and cutting the main wire."
+ icon_state = "recipient"
+
+ buffer = 150
+
+ ///How much chemicals we can teleport per process
+ var/pull_amount = 20
+ ///All synced up chemical beacons we can tap from
+ var/list/senders = list()
+ ///We only grab one machine per process, so store which one is next
+ var/next_index = 1
+
+/obj/machinery/plumbing/receiver/Initialize(mapload, bolt)
+ . = ..()
+ AddComponent(/datum/component/plumbing/simple_supply, bolt)
+
+/obj/machinery/plumbing/receiver/multitool_act(mob/living/user, obj/item/I)
+ if(!multitool_check_buffer(user, I))
+ return
+
+ var/obj/item/multitool/M = I
+ M.buffer = src
+ to_chat(user, "You store linkage information in [I]'s buffer.")
+ return TRUE
+
+/obj/machinery/plumbing/receiver/process()
+ if(machine_stat & NOPOWER || panel_open)
+ return
+
+ if(senders.len)
+ if(senders.len < next_index)
+ next_index = 1
+
+ var/obj/machinery/plumbing/sender/S = senders[next_index]
+ if(QDELETED(S))
+ senders.Remove(S)
+ return
+
+ S.teleport_chemicals(src, pull_amount)
+
+ flick(initial(icon_state) + "_flash", src)
+
+ next_index++
+
+///Notify all senders to forget us
+/obj/machinery/plumbing/receiver/proc/lose_senders()
+ for(var/A in senders)
+ var/obj/machinery/plumbing/sender/S = A
+ if(S == null)
+ continue
+ S.lose_teleport_target()
+
+ senders = list()
+
+/obj/machinery/plumbing/receiver/attackby(obj/item/I, mob/user, params)
+ if(default_deconstruction_screwdriver(user, icon_state + "_open", initial(icon_state), I))
+ update_icon()
+ return
+
+ if(default_pry_open(I))
+ return
+
+ if(default_deconstruction_crowbar(I))
+ return
+
+ return ..()
+
+/obj/machinery/plumbing/receiver/wirecutter_act(mob/living/user, obj/item/I)
+ . = ..()
+
+ if(panel_open)
+ lose_senders()
diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm
index 19ba8458e6e..ed90b28e523 100644
--- a/code/modules/research/designs/machine_designs.dm
+++ b/code/modules/research/designs/machine_designs.dm
@@ -609,6 +609,15 @@
category = list ("Medical Machinery")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+/datum/design/board/plumbing_receiver
+ name = "Machine Design (Chemical Recipient)"
+ desc = "The circuit board for a Chemical Recipient."
+ id = "plumbing_receiver"
+ build_path = /obj/item/circuitboard/machine/plumbing_receiver
+ category = list ("Teleportation Machinery")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+
+
/datum/design/board/sheetifier
name = "Machine Design (Sheet-meister 2000)"
desc = "The circuit board for a Sheet-meister 2000."
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index b2c91506143..48642bbfed7 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -227,7 +227,7 @@
display_name = "Applied Bluespace Research"
description = "Using bluespace to make things faster and better."
prereq_ids = list("bluespace_basic", "engineering")
- design_ids = list("bs_rped","minerbag_holding", "bluespacebeaker", "bluespacesyringe", "phasic_scanning", "roastingstick", "ore_silo")
+ design_ids = list("bs_rped","minerbag_holding", "bluespacebeaker", "bluespacesyringe", "phasic_scanning", "roastingstick", "ore_silo", "plumbing_receiver")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
export_price = 5000
diff --git a/icons/obj/plumbing/plumbers.dmi b/icons/obj/plumbing/plumbers.dmi
index 56f6984e472..07daa59cd42 100644
Binary files a/icons/obj/plumbing/plumbers.dmi and b/icons/obj/plumbing/plumbers.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 038446d95d0..d07869867a8 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -178,6 +178,7 @@
#include "code\_globalvars\lists\achievements.dm"
#include "code\_globalvars\lists\admin.dm"
#include "code\_globalvars\lists\client.dm"
+#include "code\_globalvars\lists\construction.dm"
#include "code\_globalvars\lists\color.dm"
#include "code\_globalvars\lists\flavor_misc.dm"
#include "code\_globalvars\lists\keybindings.dm"
@@ -2619,6 +2620,7 @@
#include "code\modules\plumbing\plumbers\reaction_chamber.dm"
#include "code\modules\plumbing\plumbers\splitters.dm"
#include "code\modules\plumbing\plumbers\synthesizer.dm"
+#include "code\modules\plumbing\plumbers\teleporter.dm"
#include "code\modules\power\apc.dm"
#include "code\modules\power\cable.dm"
#include "code\modules\power\cell.dm"