diff --git a/_maps/map_files/Donutstation/Donutstation.dmm b/_maps/map_files/Donutstation/Donutstation.dmm
index 3eb7ca9fbd5..c4f80e7b2e6 100644
--- a/_maps/map_files/Donutstation/Donutstation.dmm
+++ b/_maps/map_files/Donutstation/Donutstation.dmm
@@ -3749,8 +3749,7 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{
dir = 4
},
-/obj/machinery/power/deck_relay,
-/obj/structure/cable,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plating,
/area/maintenance/port/aft)
"ajl" = (
@@ -6299,8 +6298,7 @@
/turf/open/floor/plating,
/area/maintenance/department/security)
"aoI" = (
-/obj/machinery/power/deck_relay,
-/obj/structure/cable,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plating,
/area/maintenance/department/security)
"aoJ" = (
@@ -14450,8 +14448,7 @@
/turf/open/floor/plating,
/area/maintenance/fore)
"aGT" = (
-/obj/machinery/power/deck_relay,
-/obj/structure/cable,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plating,
/area/maintenance/fore)
"aGU" = (
@@ -15199,8 +15196,7 @@
/turf/open/floor/plasteel/white,
/area/medical/medbay/central)
"aIH" = (
-/obj/machinery/power/deck_relay,
-/obj/structure/cable,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
"aII" = (
@@ -22901,8 +22897,7 @@
dir = 1
},
/obj/effect/turf_decal/trimline/neutral/filled/line,
-/obj/machinery/power/deck_relay,
-/obj/structure/cable,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plasteel,
/area/maintenance/port/fore)
"bac" = (
@@ -25048,8 +25043,7 @@
/obj/effect/turf_decal/trimline/yellow/filled/corner{
dir = 1
},
-/obj/machinery/power/deck_relay,
-/obj/structure/cable,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plasteel,
/area/maintenance/aft)
"beW" = (
@@ -26110,8 +26104,7 @@
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"bhg" = (
-/obj/machinery/power/deck_relay,
-/obj/structure/cable/layer1,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plating,
/area/maintenance/port/fore)
"bhi" = (
@@ -26657,8 +26650,7 @@
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"bin" = (
-/obj/machinery/power/deck_relay,
-/obj/structure/cable,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plasteel/dark,
/area/engine/engine_room)
"bip" = (
@@ -31534,8 +31526,7 @@
/turf/closed/wall,
/area/tcommsat/computer)
"bsi" = (
-/obj/structure/cable,
-/obj/machinery/power/deck_relay,
+/obj/structure/cable/multilayer/multiz,
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 8
@@ -40745,8 +40736,7 @@
/area/security/prison/visit)
"bLd" = (
/obj/machinery/light/small,
-/obj/machinery/power/deck_relay,
-/obj/structure/cable,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plating,
/area/security/prison)
"bLi" = (
diff --git a/_maps/map_files/Donutstation/Donutstation_LVL2.dmm b/_maps/map_files/Donutstation/Donutstation_LVL2.dmm
index 9109b5311d9..1e92ad7c834 100644
--- a/_maps/map_files/Donutstation/Donutstation_LVL2.dmm
+++ b/_maps/map_files/Donutstation/Donutstation_LVL2.dmm
@@ -2571,8 +2571,7 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{
dir = 4
},
-/obj/machinery/power/deck_relay,
-/obj/structure/cable,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plating,
/area/maintenance/central)
"fS" = (
@@ -3701,8 +3700,7 @@
/obj/effect/turf_decal/trimline/neutral/filled/line{
dir = 1
},
-/obj/structure/cable,
-/obj/machinery/power/deck_relay,
+/obj/structure/cable/multilayer/multiz,
/obj/machinery/light{
dir = 1
},
@@ -4598,8 +4596,7 @@
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/ai)
"jY" = (
-/obj/machinery/power/deck_relay,
-/obj/structure/cable,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/ai)
"jZ" = (
@@ -5474,8 +5471,7 @@
/turf/open/floor/plating,
/area/maintenance/fore/upper)
"lR" = (
-/obj/machinery/power/deck_relay,
-/obj/structure/cable,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plating,
/area/maintenance/fore/upper)
"lS" = (
@@ -6120,8 +6116,7 @@
dir = 1
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
-/obj/machinery/power/deck_relay,
-/obj/structure/cable,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plasteel,
/area/maintenance/external/port/bow)
"no" = (
@@ -7084,8 +7079,7 @@
/turf/open/floor/plating,
/area/engine/gravity_generator)
"px" = (
-/obj/machinery/power/deck_relay,
-/obj/structure/cable/layer1,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plating,
/area/engine/gravity_generator)
"py" = (
@@ -8776,11 +8770,10 @@
/turf/open/floor/plasteel,
/area/maintenance/external/aft)
"sN" = (
-/obj/machinery/power/deck_relay,
+/obj/structure/cable/multilayer/multiz,
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 6
},
-/obj/structure/cable,
/obj/effect/turf_decal/trimline/yellow/filled/corner{
dir = 1
},
@@ -13684,8 +13677,7 @@
/turf/open/floor/plating,
/area/maintenance/solars/port/fore)
"BS" = (
-/obj/machinery/power/deck_relay,
-/obj/structure/cable,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plating,
/area/maintenance/solars/port/fore)
"BT" = (
@@ -15495,8 +15487,7 @@
/turf/open/floor/plating,
/area/maintenance/department/security/upper)
"Go" = (
-/obj/machinery/power/deck_relay,
-/obj/structure/cable,
+/obj/structure/cable/multilayer/multiz,
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
@@ -19899,8 +19890,7 @@
/area/security/prison/upper)
"Pk" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
-/obj/structure/cable,
-/obj/machinery/power/deck_relay,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plating,
/area/security/prison/upper)
"Pl" = (
diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm
index 720de7ae651..8d58c74cd06 100644
--- a/_maps/map_files/KiloStation/KiloStation.dmm
+++ b/_maps/map_files/KiloStation/KiloStation.dmm
@@ -74275,9 +74275,9 @@
/obj/effect/turf_decal/stripes/line{
dir = 5
},
-/obj/structure/cable,
-/obj/structure/cable_bridge,
-/obj/structure/cable/layer3,
+/obj/structure/cable/multilayer{
+ cable_layer = 6
+ },
/turf/open/floor/engine,
/area/ai_monitored/storage/satellite)
"cic" = (
diff --git a/_maps/map_files/debug/multiz.dmm b/_maps/map_files/debug/multiz.dmm
index 02c0a828f4f..2f24af453e6 100644
--- a/_maps/map_files/debug/multiz.dmm
+++ b/_maps/map_files/debug/multiz.dmm
@@ -1183,8 +1183,7 @@
/turf/open/floor/plating,
/area/space)
"iq" = (
-/obj/machinery/power/deck_relay,
-/obj/structure/cable,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plating,
/area/construction)
"iu" = (
@@ -1273,8 +1272,7 @@
/turf/open/floor/plasteel,
/area/engine/storage)
"nF" = (
-/obj/structure/cable,
-/obj/machinery/power/deck_relay,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plating,
/area/hallway/secondary/service)
"od" = (
@@ -1773,8 +1771,7 @@
/turf/open/floor/plating,
/area/engine/storage)
"Vm" = (
-/obj/machinery/power/deck_relay,
-/obj/structure/cable,
+/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plating,
/area/engine/storage)
"Vn" = (
diff --git a/code/__DEFINES/power.dm b/code/__DEFINES/power.dm
index 0688f8e7d9d..fa145bbea1b 100644
--- a/code/__DEFINES/power.dm
+++ b/code/__DEFINES/power.dm
@@ -2,6 +2,8 @@
#define CABLE_LAYER_2 2
#define CABLE_LAYER_3 4
+#define MACHINERY_LAYER_1 1
+
#define SOLAR_TRACK_OFF 0
#define SOLAR_TRACK_TIMED 1
#define SOLAR_TRACK_AUTO 2
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index c375fbc1014..2ad38e18c5f 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -1,6 +1,6 @@
//Use this only for things that aren't a subtype of obj/machinery/power
//For things that are, override "should_have_node()" on them
-GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(/obj/structure/grille, /obj/structure/cable_bridge)))
+GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(/obj/structure/grille)))
#define UNDER_SMES -1
#define UNDER_TERMINAL 1
@@ -22,18 +22,21 @@ GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(/obj/structure/gri
obj_flags = CAN_BE_HIT | ON_BLUEPRINTS
var/linked_dirs = 0 //bitflag
var/node = FALSE //used for sprites display
- var/cable_layer = CABLE_LAYER_2
+ var/cable_layer = CABLE_LAYER_2 //bitflag
+ var/machinery_layer = MACHINERY_LAYER_1 //bitflag
var/datum/powernet/powernet
/obj/structure/cable/layer1
color = "red"
cable_layer = CABLE_LAYER_1
+ machinery_layer = null
layer = WIRE_LAYER - 0.01
icon_state = "l1-1-2-4-8-node"
/obj/structure/cable/layer3
color = "blue"
cable_layer = CABLE_LAYER_3
+ machinery_layer = null
layer = WIRE_LAYER + 0.01
icon_state = "l3-1-2-4-8-node"
@@ -41,11 +44,12 @@ GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(/obj/structure/gri
. = ..()
GLOB.cable_list += src //add it to the global cable list
- connect_wire()
-
+ Connect_cable()
AddElement(/datum/element/undertile, TRAIT_T_RAY_VISIBLE)
-/obj/structure/cable/proc/connect_wire(clear_before_updating = FALSE)
+
+///Set the linked indicator bitflags
+/obj/structure/cable/proc/Connect_cable(clear_before_updating = FALSE)
var/under_thing = NONE
if(clear_before_updating)
linked_dirs = 0
@@ -87,8 +91,8 @@ GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(/obj/structure/gri
update_icon()
-/obj/structure/cable/Destroy() // called when a cable is deleted
- //Clear the linked indicator bitflags
+///Clear the linked indicator bitflags
+/obj/structure/cable/proc/Disconnect_cable()
for(var/check_dir in GLOB.cardinals)
var/inverse = turn(check_dir, 180)
if(linked_dirs & check_dir)
@@ -98,6 +102,9 @@ GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(/obj/structure/gri
C.linked_dirs &= ~inverse
C.update_icon()
+/obj/structure/cable/Destroy() // called when a cable is deleted
+ Disconnect_cable()
+
if(powernet)
cut_cable_from_powernet() // update the powernets
GLOB.cable_list -= src //remove it from global cable list
@@ -106,7 +113,7 @@ GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(/obj/structure/gri
/obj/structure/cable/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
- new /obj/item/stack/cable_coil(get_turf(loc), 1)
+ new /obj/item/stack/cable_coil(drop_location(), 1)
qdel(src)
///////////////////////////////////
@@ -298,10 +305,6 @@ GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(/obj/structure/gri
/obj/structure/cable/proc/get_cable_connections(powernetless_only)
. = list()
var/turf/T = get_turf(src)
- if(locate(/obj/structure/cable_bridge) in T)
- for(var/obj/structure/cable/C in T)
- if(C != src)
- . += C
for(var/check_dir in GLOB.cardinals)
if(linked_dirs & check_dir)
T = get_step(src, check_dir)
@@ -309,6 +312,14 @@ GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(/obj/structure/gri
if(cable_layer & C.cable_layer)
. += C
+/obj/structure/cable/proc/get_all_cable_connections(powernetless_only)
+ . = list()
+ var/turf/T
+ for(var/check_dir in GLOB.cardinals)
+ T = get_step(src, check_dir)
+ for(var/obj/structure/cable/C in T.contents - src)
+ . += C
+
/obj/structure/cable/proc/get_machine_connections(powernetless_only)
. = list()
for(var/obj/machinery/power/P in get_turf(src))
@@ -316,14 +327,14 @@ GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(/obj/structure/gri
if(P.anchored)
. += P
-/obj/structure/cable/proc/auto_propogate_cut_cable(obj/O)
+/obj/structure/cable/proc/auto_propagate_cut_cable(obj/O)
if(O && !QDELETED(O))
var/datum/powernet/newPN = new()// creates a new powernet...
propagate_network(O, newPN)//... and propagates it to the other side of the cable
//Makes a new network for the cable and propgates it.
-//If it finds another network in the process, aborts and uses that one and propogates off of it instead
-/obj/structure/cable/proc/propogate_if_no_network()
+//If it finds another network in the process, aborts and uses that one and propagates off of it instead
+/obj/structure/cable/proc/propagate_if_no_network()
if(powernet)
return
var/datum/powernet/newPN = new()
@@ -358,7 +369,7 @@ GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(/obj/structure/gri
if(first)
first = FALSE
continue
- addtimer(CALLBACK(O, .proc/auto_propogate_cut_cable, O), 0) //so we don't rebuild the network X times when singulo/explosion destroys a line of X cables
+ addtimer(CALLBACK(O, .proc/auto_propagate_cut_cable, O), 0) //so we don't rebuild the network X times when singulo/explosion destroys a line of X cables
///////////////////////////////////////////////
// The cable coil object, used for laying cable
@@ -368,8 +379,7 @@ GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(/obj/structure/gri
// Definitions
////////////////////////////////
-GLOBAL_LIST_INIT(cable_coil_recipes, list(new/datum/stack_recipe("cable restraints", /obj/item/restraints/handcuffs/cable, 15),
- new/datum/stack_recipe("cable bridge", /obj/structure/cable_bridge, 15)))
+GLOBAL_LIST_INIT(cable_coil_recipes, list(new/datum/stack_recipe("cable restraints", /obj/item/restraints/handcuffs/cable, 15), new/datum/stack_recipe("multilayer cable", /obj/structure/cable/multilayer, 1), new/datum/stack_recipe("multiZ cable", /obj/structure/cable/multilayer/multiz, 1)))
/obj/item/stack/cable_coil
name = "cable coil"
@@ -399,6 +409,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list(new/datum/stack_recipe("cable restrain
grind_results = list(/datum/reagent/copper = 2) //2 copper per cable in the coil
usesound = 'sound/items/deconstruct.ogg'
var/obj/structure/cable/target_type = /obj/structure/cable
+ var/target_layer = CABLE_LAYER_2
/obj/item/stack/cable_coil/Initialize(mapload, new_amount = null)
. = ..()
@@ -425,29 +436,56 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list(new/datum/stack_recipe("cable restrain
return FALSE
return TRUE
+GLOBAL_LIST(cable_radial_layer_list)
+
/obj/item/stack/cable_coil/CtrlClick(mob/living/user)
if(loc!=user)
return ..()
if(!user)
return
- var/list/layer_list = list(
+ if(!GLOB.cable_radial_layer_list)
+ GLOB.cable_radial_layer_list = list(
"Layer 1" = image(icon = 'icons/mob/radial.dmi', icon_state = "coil-red"),
"Layer 2" = image(icon = 'icons/mob/radial.dmi', icon_state = "coil-yellow"),
- "Layer 3" = image(icon = 'icons/mob/radial.dmi', icon_state = "coil-blue")
+ "Layer 3" = image(icon = 'icons/mob/radial.dmi', icon_state = "coil-blue"),
+ "Multilayer cable hub" = image(icon = 'icons/obj/power.dmi', icon_state = "cable_bridge"),
+ "Multi Z layer cable hub" = image(icon = 'icons/obj/power.dmi', icon_state = "cablerelay-broken-cable")
)
- var/layer_result = show_radial_menu(user, src, layer_list, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
+ var/layer_result = show_radial_menu(user, src, GLOB.cable_radial_layer_list, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
if(!check_menu(user))
return
switch(layer_result)
if("Layer 1")
+ name = "cable coil"
+ icon_state = "coil"
color = "red"
target_type = /obj/structure/cable/layer1
+ target_layer = CABLE_LAYER_1
if("Layer 2")
+ name = "cable coil"
+ icon_state = "coil"
color = "yellow"
target_type = /obj/structure/cable
+ target_layer = CABLE_LAYER_2
if("Layer 3")
+ name = "cable coil"
+ icon_state = "coil"
color = "blue"
target_type = /obj/structure/cable/layer3
+ target_layer = CABLE_LAYER_3
+ if("Multilayer cable hub")
+ name = "multilayer cable hub"
+ icon_state = "cable_bridge"
+ color = "white"
+ target_type = /obj/structure/cable/multilayer
+ target_layer = CABLE_LAYER_2
+ if("Multi Z layer cable hub")
+ name = "multi z layer cable hub"
+ icon_state = "cablerelay-broken-cable"
+ color = "white"
+ target_type = /obj/structure/cable/multilayer/multiz
+ target_layer = CABLE_LAYER_2
+ update_icon()
///////////////////////////////////
@@ -470,11 +508,6 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list(new/datum/stack_recipe("cable restrain
else
return ..()
-
-/obj/item/stack/cable_coil/update_icon()
- icon_state = "[initial(item_state)][amount < 3 ? amount : ""]"
- name = "cable [amount < 3 ? "piece" : "coil"]"
-
//add cables to the stack
/obj/item/stack/cable_coil/proc/give(extra)
if(amount + extra > max_amount)
@@ -506,7 +539,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list(new/datum/stack_recipe("cable restrain
return
for(var/obj/structure/cable/C in T)
- if(target_type == C.type)
+ if(C.cable_layer & target_layer)
to_chat(user, "There's already a cable at that position!")
return
@@ -549,32 +582,161 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list(new/datum/stack_recipe("cable restrain
custom_materials = list()
cost = 1
-/obj/structure/cable_bridge
- name = "cable bridge"
- desc = "A bridge to connect different cable layers, or link terminals to incompatible cable layers."
- icon = 'icons/obj/power.dmi'
- icon_state = "cable_bridge"
- layer = WIRE_LAYER + 0.02 //Above all the cables but below terminals
- anchored = TRUE
- obj_flags = CAN_BE_HIT | ON_BLUEPRINTS
-
-/obj/structure/cable_bridge/Initialize(mapload)
- . = ..()
- if (!mapload)
- var/first = TRUE
- var/datum/powernet/PN
- for(var/obj/structure/cable/C in get_turf(src))
- C.update_icon()
- if(first == TRUE)
- first = FALSE
- PN = C.powernet
- continue
- propagate_network(C, PN)
-
-/obj/structure/cable_bridge/wirecutter_act(mob/living/user, obj/item/I)
- . = ..()
- qdel(src)
- return TRUE
-
#undef UNDER_SMES
#undef UNDER_TERMINAL
+
+///multilayer cable to connect different layers
+/obj/structure/cable/multilayer
+ name = "multilayer cable hub"
+ desc = "A flexible, superconducting insulated multilayer hub for heavy-duty multilayer power transfer."
+ icon = 'icons/obj/power.dmi'
+ icon_state = "cable_bridge"
+ cable_layer = CABLE_LAYER_2
+ machinery_layer = MACHINERY_LAYER_1
+ layer = WIRE_LAYER - 0.02 //Below all cables Disabled layers can lay over hub
+ color = "white"
+ var/obj/effect/node/machinery_node
+ var/obj/effect/node/layer1/cable_node_1
+ var/obj/effect/node/layer2/cable_node_2
+ var/obj/effect/node/layer3/cable_node_3
+
+/obj/effect/node
+ icon = 'icons/obj/power_cond/layer_cable.dmi'
+ icon_state = "l2-noconnection"
+ vis_flags = VIS_INHERIT_ID|VIS_INHERIT_PLANE|VIS_INHERIT_LAYER
+ color = "black"
+
+/obj/effect/node/layer1
+ color = "red"
+ icon_state = "l1-1-2-4-8-node"
+ vis_flags = VIS_INHERIT_ID|VIS_INHERIT_PLANE|VIS_INHERIT_LAYER|VIS_UNDERLAY
+
+/obj/effect/node/layer2
+ color = "yellow"
+ icon_state = "l2-1-2-4-8-node"
+ vis_flags = VIS_INHERIT_ID|VIS_INHERIT_PLANE|VIS_INHERIT_LAYER|VIS_UNDERLAY
+
+/obj/effect/node/layer3
+ color = "blue"
+ icon_state = "l4-1-2-4-8-node"
+ vis_flags = VIS_INHERIT_ID|VIS_INHERIT_PLANE|VIS_INHERIT_LAYER|VIS_UNDERLAY
+
+/obj/structure/cable/multilayer/update_icon_state()
+ return
+
+/obj/structure/cable/multilayer/update_icon()
+ var/R = 50
+ var/G = 50
+ var/B = 50
+
+ R += cable_layer & CABLE_LAYER_1 ? 150 : 0
+ G += cable_layer & CABLE_LAYER_2 ? 150 : 0
+ B += cable_layer & CABLE_LAYER_3 ? 150 : 0
+
+ color = rgb(R, G, B)
+
+ machinery_node?.alpha = machinery_layer & MACHINERY_LAYER_1 ? 255 : 0
+
+ cable_node_1?.alpha = cable_layer & CABLE_LAYER_1 ? 255 : 0
+
+ cable_node_2?.alpha = cable_layer & CABLE_LAYER_2 ? 255 : 0
+
+ cable_node_3?.alpha = cable_layer & CABLE_LAYER_3 ? 255 : 0
+
+ return ..()
+
+/obj/structure/cable/multilayer/Initialize(mapload)
+ . = ..()
+
+ var/turf/T = get_turf(src)
+ for(var/obj/structure/cable/C in T.contents - src)
+ if(C.cable_layer & cable_layer)
+ C.deconstruct() // remove adversary cable
+ if(!mapload)
+ auto_propagate_cut_cable(src)
+
+ machinery_node = new /obj/effect/node()
+ vis_contents += machinery_node
+ cable_node_1 = new /obj/effect/node/layer1()
+ vis_contents += cable_node_1
+ cable_node_2 = new /obj/effect/node/layer2()
+ vis_contents += cable_node_2
+ cable_node_3 = new /obj/effect/node/layer3()
+ vis_contents += cable_node_3
+ update_icon()
+
+/obj/structure/cable/multilayer/Destroy() // called when a cable is deleted
+ QDEL_NULL(machinery_node)
+ QDEL_NULL(cable_node_1)
+ QDEL_NULL(cable_node_2)
+ QDEL_NULL(cable_node_3)
+ return ..() // then go ahead and delete the cable
+
+/obj/structure/cable/multilayer/examine(mob/user)
+ . += ..()
+ . += "L1:[cable_layer & CABLE_LAYER_1 ? "Connect" : "Disconnect"]."
+ . += "L2:[cable_layer & CABLE_LAYER_2 ? "Connect" : "Disconnect"]."
+ . += "L3:[cable_layer & CABLE_LAYER_3 ? "Connect" : "Disconnect"]."
+ . += "M:[machinery_layer & MACHINERY_LAYER_1 ? "Connect" : "Disconnect"]."
+
+GLOBAL_LIST(hub_radial_layer_list)
+
+/obj/structure/cable/multilayer/attack_hand(mob/living/user)
+ if(!user)
+ return
+ if(!GLOB.hub_radial_layer_list)
+ GLOB.hub_radial_layer_list = list(
+ "Layer 1" = image(icon = 'icons/mob/radial.dmi', icon_state = "coil-red"),
+ "Layer 2" = image(icon = 'icons/mob/radial.dmi', icon_state = "coil-yellow"),
+ "Layer 3" = image(icon = 'icons/mob/radial.dmi', icon_state = "coil-blue"),
+ "Machinery" = image(icon = 'icons/obj/power.dmi', icon_state = "smes")
+ )
+
+ var/layer_result = show_radial_menu(user, src, GLOB.hub_radial_layer_list, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
+ if(!check_menu(user))
+ return
+ var/CL
+ switch(layer_result)
+ if("Layer 1")
+ CL = CABLE_LAYER_1
+ to_chat(user, "You toggle L1 connection.")
+ if("Layer 2")
+ CL = CABLE_LAYER_2
+ to_chat(user, "You toggle L2 connection.")
+ if("Layer 3")
+ CL = CABLE_LAYER_3
+ to_chat(user, "You toggle L3 connection.")
+ if("Machinery")
+ machinery_layer ^= MACHINERY_LAYER_1
+ to_chat(user, "You toggle machinery connection.")
+
+ cut_cable_from_powernet(FALSE)
+
+ Disconnect_cable()
+
+ cable_layer ^= CL
+
+ Connect_cable(TRUE)
+
+ Reload()
+
+/obj/structure/cable/multilayer/proc/check_menu(mob/living/user)
+ if(!istype(user))
+ return FALSE
+ if(user.incapacitated() || !user.Adjacent(src))
+ return FALSE
+ return TRUE
+
+///Reset powernet in this hub.
+/obj/structure/cable/multilayer/proc/Reload()
+ var/turf/T = get_turf(src)
+ for(var/obj/structure/cable/C in T.contents - src)
+ if(C.cable_layer & cable_layer)
+ C.deconstruct() // remove adversary cable
+ auto_propagate_cut_cable(src) // update the powernets
+
+/obj/structure/cable/multilayer/CtrlClick(mob/living/user)
+ to_chat(user, "You pust reset button.")
+ addtimer(CALLBACK(src, .proc/Reload), 10, TIMER_UNIQUE) //spam protect
+
+
diff --git a/code/modules/power/multiz.dm b/code/modules/power/multiz.dm
index 3ad0d8be6df..969db61d3b3 100644
--- a/code/modules/power/multiz.dm
+++ b/code/modules/power/multiz.dm
@@ -1,144 +1,20 @@
-#define RELAY_OK 1
-#define RELAY_ADD_CABLE 2
-#define RELAY_ADD_METAL 3
-
-/obj/machinery/power/deck_relay //This bridges powernets
- name = "Multi-deck power adapter"
- desc = "A huge bundle of double insulated cabling which seems to run up into the ceiling."
+/obj/structure/cable/multilayer/multiz //This bridges powernets betwen Z levels
+ name = "multi z layer cable hub"
+ desc = "A flexible, superconducting insulated multi Z layer hub for heavy-duty multi Z power transfer."
icon = 'icons/obj/power.dmi'
- icon_state = "cablerelay-off"
- max_integrity = 350
- integrity_failure = 0.25
- var/broken_status = RELAY_OK
- var/obj/machinery/power/deck_relay/below ///The relay that's below us (for bridging powernets)
- var/obj/machinery/power/deck_relay/above ///The relay that's above us (for bridging powernets)
- anchored = TRUE
- density = FALSE
+ icon_state = "cablerelay-on"
+ cable_layer = CABLE_LAYER_1|CABLE_LAYER_2|CABLE_LAYER_3
+ machinery_layer = null
-/obj/machinery/power/deck_relay/examine(mob/user)
- . += ..()
- if(!anchored)
- . += "The securing bolts are undone."
- if(broken_status == RELAY_ADD_CABLE)
- . += "The cable insulation is torn apart and the wires are frayed beyond use."
- if(broken_status == RELAY_ADD_METAL)
- . += "The cable insulation is torn apart and the wiring is exposed."
-
-/obj/machinery/power/deck_relay/attackby(obj/item/I, mob/user, params)
- if(default_unfasten_wrench(user, I))
- if(!anchored && broken_status == RELAY_OK)
- break_connections()
- return FALSE
-
- else if(istype(I, /obj/item/stack/cable_coil) && broken_status == RELAY_ADD_CABLE)
- var/obj/item/stack/C = I
- if(C.use(15))
- to_chat(user, "You fix the frayed wires inside [src].")
- icon_state = "cablerelay-broken-cable"
- broken_status = RELAY_ADD_METAL
- else
- to_chat(user, "You need 15 cables to rewire [src].")
-
- else if(istype(I, /obj/item/stack/sheet/metal) && broken_status == RELAY_ADD_METAL)
- var/obj/item/stack/S = I
- if(S.use(10))
- to_chat(user, "You reseal the insulation for [src].")
- icon_state = "cablerelay"
- broken_status = RELAY_OK
- obj_integrity = max_integrity
- else
- to_chat(user, "You need 10 metal to mend [src].")
-
- else
- return ..()
-
-/obj/machinery/power/deck_relay/obj_break()
- ..()
- if(broken_status == RELAY_OK)
- break_connections()
- visible_message("[src]'s insulation breaks, fraying and severing the cable bundle!")
- playsound(loc, 'sound/effects/glassbr3.ogg', 100, TRUE)
- icon_state = "cablerelay-broken"
- broken_status = RELAY_ADD_CABLE
-
-/obj/machinery/power/deck_relay/obj_destruction()
- return //this shouldn't break under usual means
-
-/obj/machinery/power/deck_relay/Destroy()
- break_connections()
- return ..()
-
-///Lose connections and reset the merged powernet so it makes 2 new seperated ones
-/obj/machinery/power/deck_relay/proc/break_connections()
- if(above)
- var/turf/above_deck_relay = get_turf(above)
- var/obj/structure/cable/above_cable = above_deck_relay.get_cable_node()
- if(above_cable)
- var/datum/powernet/above_powernet = new()
- propagate_network(above_cable, above_powernet)
- above.below = null
- above = null
- if(below)
- var/turf/below_deck_relay = get_turf(below)
- var/obj/structure/cable/below_cable = below_deck_relay.get_cable_node()
- if(below_cable)
- var/datum/powernet/below_powernet = new()
- propagate_network(below_cable, below_powernet)
- below.above = null
- below = null
-
-///Allows you to scan the relay with a multitool to see stats/reconnect relays
-/obj/machinery/power/deck_relay/multitool_act(mob/user, obj/item/I)
- if(!anchored)
- to_chat(user, "You need to wrench this into place before getting a reading!")
- return TRUE
- if(broken_status == RELAY_ADD_CABLE || broken_status == RELAY_ADD_METAL)
- to_chat(user, "The [src] isn't in proper shape to get a reading!")
- return TRUE
- if(powernet && (above || below))//we have a powernet and at least one connected relay
- to_chat(user, "Total power: [DisplayPower(powernet.avail)]\nLoad: [DisplayPower(powernet.load)]\nExcess power: [DisplayPower(surplus())]")
- if(!above && !below)
- to_chat(user, "Cannot access valid powernet. Attempting to re-establish. Ensure any relays above and below are aligned properly and on cable nodes.")
- find_relays()
- addtimer(CALLBACK(src, .proc/refresh), 20) //Wait a bit so we can find the one below, then get powering
- return TRUE
-
-/obj/machinery/power/deck_relay/Initialize()
+/obj/structure/cable/multilayer/multiz/get_cable_connections(powernetless_only)
. = ..()
- addtimer(CALLBACK(src, .proc/find_relays), 30)
- addtimer(CALLBACK(src, .proc/refresh), 50) //Wait a bit so we can find the one below, then get powering
-
-///Handles re-acquiring + merging powernets found by find_relays()
-/obj/machinery/power/deck_relay/proc/refresh()
- if(above)
- above.merge(src)
- if(below)
- below.merge(src)
-
-///Merges the two powernets connected to the deck relays
-/obj/machinery/power/deck_relay/proc/merge(var/obj/machinery/power/deck_relay/DR)
- if(!DR)
- return
- var/turf/merge_from = get_turf(DR)
- var/turf/merge_to = get_turf(src)
- var/obj/structure/cable/C = merge_from.get_cable_node()
- var/obj/structure/cable/XR = merge_to.get_cable_node()
- if(C && XR)
- merge_powernets(XR.powernet,C.powernet)//Bridge the powernets.
-
-///Locates relays that are above and below this object
-/obj/machinery/power/deck_relay/proc/find_relays()
var/turf/T = get_turf(src)
- if(!T || !istype(T))
- return FALSE
- below = null //in case we're re-establishing
- above = null
- var/obj/structure/cable/C = T.get_cable_node() //check if we have a node cable on the machine turf, the first found is picked
- if(C && C.powernet)
- C.powernet.add_machine(src) //Nice we're in.
- powernet = C.powernet
- below = locate(/obj/machinery/power/deck_relay) in(SSmapping.get_turf_below(T))
- above = locate(/obj/machinery/power/deck_relay) in(SSmapping.get_turf_above(T))
- if(below || above)
- icon_state = "cablerelay-on"
- return TRUE
+ . += locate(/obj/structure/cable/multilayer/multiz) in (SSmapping.get_turf_below(T))
+ . += locate(/obj/structure/cable/multilayer/multiz) in (SSmapping.get_turf_above(T))
+
+/obj/structure/cable/multilayer/examine(mob/user)
+ . += ..()
+ var/turf/T = get_turf(src)
+ . += "[locate(/obj/structure/cable/multilayer/multiz) in (SSmapping.get_turf_below(T)) ? "Detected" : "Undetected"] hub UP."
+ . += "[locate(/obj/structure/cable/multilayer/multiz) in (SSmapping.get_turf_above(T)) ? "Detected" : "Undetected"] hub DOWN."
+
diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm
index 7fef862f9db..8ffb41c4570 100644
--- a/code/modules/power/power.dm
+++ b/code/modules/power/power.dm
@@ -15,6 +15,7 @@
use_power = NO_POWER_USE
idle_power_usage = 0
active_power_usage = 0
+ var/machinery_layer = MACHINERY_LAYER_1 //cable layer to which the machine is connected
/obj/machinery/power/Destroy()
disconnect_from_network()
@@ -138,7 +139,7 @@
if(!T || !istype(T))
return FALSE
- var/obj/structure/cable/C = T.get_cable_node() //check if we have a node cable on the machine turf, the first found is picked
+ var/obj/structure/cable/C = T.get_cable_node(machinery_layer) //check if we have a node cable on the machine turf, the first found is picked
if(!C || !C.powernet)
var/obj/machinery/power/terminal/term = locate(/obj/machinery/power/terminal) in T
if(!term || !term.powernet)
@@ -353,13 +354,12 @@
// Misc.
///////////////////////////////////////////////
-// return a cable if there's one on the turf, null if there isn't one
-/turf/proc/get_cable_node(check_layer = CABLE_LAYER_2)
+// return a cable able connect to machinery on layer if there's one on the turf, null if there isn't one
+/turf/proc/get_cable_node(machinery_layer = MACHINERY_LAYER_1)
if(!can_have_cabling())
return null
- var/obj/structure/cable_bridge/B = locate() in src
for(var/obj/structure/cable/C in src)
- if(C.cable_layer & check_layer || B)
+ if(C.machinery_layer & machinery_layer)
C.update_icon()
return C
return null
diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm
index e2035244bff..bf2c1ceee54 100644
--- a/code/modules/shuttle/on_move.dm
+++ b/code/modules/shuttle/on_move.dm
@@ -332,8 +332,8 @@ All ShuttleMove procs go here
/obj/structure/cable/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
. = ..()
- connect_wire(TRUE)
- propogate_if_no_network()
+ Connect_cable(TRUE)
+ propagate_if_no_network()
/obj/structure/shuttle/beforeShuttleMove(turf/newT, rotation, move_mode, obj/docking_port/mobile/moving_dock)
. = ..()