diff --git a/_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm b/_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm
index fa251604932..018a01b3938 100644
--- a/_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm
+++ b/_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm
@@ -4,9 +4,8 @@
/area/space)
"ab" = (
/obj/machinery/shieldwallgen{
- active = 2;
- anchored = 1;
- power = 1
+ activated = 1;
+ anchored = 1
},
/obj/structure/cable{
d2 = 4;
@@ -26,9 +25,8 @@
/area/ruin/space/unpowered)
"ad" = (
/obj/machinery/shieldwallgen{
- active = 2;
- anchored = 1;
- power = 1
+ activated = 1;
+ anchored = 1
},
/obj/structure/cable{
d2 = 2;
@@ -43,9 +41,8 @@
/area/ruin/space/unpowered)
"ae" = (
/obj/machinery/shieldwallgen{
- active = 2;
- anchored = 1;
- power = 1
+ activated = 1;
+ anchored = 1
},
/obj/structure/cable{
d1 = 2;
@@ -61,9 +58,8 @@
/area/ruin/space/unpowered)
"af" = (
/obj/machinery/shieldwallgen{
- active = 2;
- anchored = 1;
- power = 1
+ activated = 1;
+ anchored = 1
},
/obj/structure/cable{
d2 = 8;
@@ -210,9 +206,8 @@
/area/ruin/space/unpowered)
"aE" = (
/obj/machinery/shieldwallgen{
- active = 2;
- anchored = 1;
- power = 1
+ activated = 1;
+ anchored = 1
},
/obj/structure/cable{
d2 = 2;
@@ -278,9 +273,8 @@
/area/ruin/space/unpowered)
"aJ" = (
/obj/machinery/shieldwallgen{
- active = 2;
- anchored = 1;
- power = 1
+ activated = 1;
+ anchored = 1
},
/obj/structure/cable{
d1 = 4;
@@ -561,9 +555,8 @@
/area/ruin/space/unpowered)
"bo" = (
/obj/machinery/shieldwallgen{
- active = 2;
- anchored = 1;
- power = 1
+ activated = 1;
+ anchored = 1
},
/obj/structure/cable{
d1 = 1;
@@ -761,9 +754,8 @@
/area/space/nearstation)
"bQ" = (
/obj/machinery/shieldwallgen{
- active = 2;
- anchored = 1;
- power = 1
+ activated = 1;
+ anchored = 1
},
/obj/structure/cable{
d1 = 1;
diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm
index 2f2a5ef85f8..7c978170caa 100644
--- a/code/game/machinery/shieldgen.dm
+++ b/code/game/machinery/shieldgen.dm
@@ -296,7 +296,7 @@
icon_state = "shield[active ? "on" : "off"][malfunction ? "br" : ""]"
////FIELD GEN START //shameless copypasta from fieldgen, powersink, and grille
-#define maxstoredpower 500
+#define MAX_STORED_POWER 500
/obj/machinery/shieldwallgen
name = "Shield Generator"
desc = "A shield generator."
@@ -305,142 +305,117 @@
anchored = FALSE
density = TRUE
req_access = list(ACCESS_TELEPORTER)
- var/active = FALSE
- var/power = FALSE
- var/state = FALSE
- var/steps = 0
+ var/activated = FALSE
var/locked = TRUE
- var/storedpower = 0
+ var/list/active_shields
+ var/stored_power = 0
flags = CONDUCT
use_power = NO_POWER_USE
-/obj/machinery/shieldwallgen/update_icon_state()
- icon_state = "Shield_Gen[active ? " +a" : ""]"
+/obj/machinery/shieldwallgen/Initialize(mapload)
+ . = ..()
+ active_shields = list() // Doing it here since you can't cast numeral defines to strings using "[NORTH]" in the definition
+ for(var/direction in GLOB.cardinal)
+ active_shields["[direction]"] = list()
+ if(!activated)
+ STOP_PROCESSING(SSmachines, src)
-/obj/machinery/shieldwallgen/proc/power()
- if(!anchored)
- power = FALSE
- return
+/obj/machinery/shieldwallgen/update_icon_state()
+ icon_state = "Shield_Gen[activated ? " +a" : ""]"
+
+/obj/machinery/shieldwallgen/proc/try_charge_shields_power()
var/turf/T = loc
var/obj/structure/cable/C = T.get_cable_node()
- var/datum/powernet/PN
- if(C)
- PN = C.powernet // find the powernet of the connected cable
+ var/datum/powernet/PN = C?.powernet // find the powernet of the connected cable
if(!PN)
- power = FALSE
- return
+ deactivate()
+ return FALSE
- var/surplus = max(PN.avail-PN.load, 0)
- var/shieldload = min(rand(50,200), surplus)
- if(shieldload == 0 && !storedpower) // no cable or no power, and no power stored
- power = FALSE
- return
- else
- power = TRUE // IVE GOT THE POWER!
- if(PN) //runtime errors fixer. They were caused by PN.load trying to access missing network in case of working on stored power.
- storedpower += shieldload
- PN.load += shieldload //uses powernet power.
-// message_admins("[PN.load]", 1)
-// use_power(250) //uses APC power
+ var/surplus = max(PN.avail - PN.load, 0)
+ var/shieldload = min(rand(50, 200), surplus)
+ if(!shieldload && stored_power <= 0) // no cable or no power, and no power stored
+ deactivate()
+ return FALSE
+
+ stored_power += min(shieldload, MAX_STORED_POWER - stored_power)
+ PN.load += shieldload //uses powernet power.
+ return TRUE
/obj/machinery/shieldwallgen/attack_hand(mob/user)
- if(state != 1)
+ if(!anchored)
to_chat(user, "The shield generator needs to be firmly secured to the floor first.")
return TRUE
if(locked && !issilicon(user))
to_chat(user, "The controls are locked!")
return TRUE
- if(!power)
+ var/turf/T = loc
+ if(!T.get_cable_node())
to_chat(user, "The shield generator needs to be powered by wire underneath.")
return TRUE
- active = !active
- user.visible_message("[user] turned the shield generator [active ? "on" : "off"].", \
- "You turn [active ? "on" : "off"] the shield generator.", \
- "You hear heavy droning [active ? "" : "fade out"].")
- if(active)
- for(var/dir in list(NORTH, SOUTH, EAST, WEST))
- cleanup(dir)
+ if(!activated)
+ activate()
+ else
+ deactivate()
+
+ user.visible_message("[user] turned the shield generator [activated ? "on" : "off"].", \
+ "You turn [activated ? "on" : "off"] the shield generator.", \
+ "You hear heavy droning [activated ? "" : "fade out"].")
+
update_icon(UPDATE_ICON_STATE)
add_fingerprint(user)
/obj/machinery/shieldwallgen/process()
- spawn(100)
- power()
- if(power)
- storedpower -= 50 //this way it can survive longer and survive at all
- if(storedpower >= maxstoredpower)
- storedpower = maxstoredpower
- if(storedpower <= 0)
- storedpower = 0
-
- if(active)
- if(state)
- active = FALSE
- return
- spawn(1)
- setup_field(1)
- spawn(2)
- setup_field(2)
- spawn(3)
- setup_field(4)
- spawn(4)
- setup_field(8)
- if(active)
- if(!power)
- visible_message("[name] shuts down due to lack of power!", \
+ if(!try_charge_shields_power())
+ visible_message("[name] shuts down due to lack of power!", \
"You hear heavy droning fade out")
- active = FALSE
- for(var/dir in list(NORTH, SOUTH, EAST, WEST))
- cleanup(dir)
- update_icon(UPDATE_ICON_STATE)
+ deactivate()
+ update_icon(UPDATE_ICON_STATE)
-/obj/machinery/shieldwallgen/proc/setup_field(NSEW = 0)
- var/turf/T = loc
- var/turf/T2 = loc
- var/obj/machinery/shieldwallgen/G
- var/steps = 0
- var/oNSEW = 0
- if(!NSEW)//Make sure its ran right
- return
+/obj/machinery/shieldwallgen/proc/activate()
+ activated = TRUE
+ START_PROCESSING(SSmachines, src)
+ for(var/direction in GLOB.cardinal)
+ INVOKE_ASYNC(src, .proc/try_link_generators, direction)
- if(NSEW == 1)
- oNSEW = 2
- else if(NSEW == 2)
- oNSEW = 1
- else if(NSEW == 4)
- oNSEW = 8
- else if(NSEW == 8)
- oNSEW = 4
-
- for(var/dist = 0, dist <= 9, dist += 1) // checks out to 8 tiles away for another generator
- T = get_step(T2, NSEW)
- T2 = T
- steps += 1
- if(locate(/obj/machinery/shieldwallgen) in T)
- G = (locate(/obj/machinery/shieldwallgen) in T)
- steps -= 1
- if(!G.active)
- return
- G.cleanup(oNSEW)
+/obj/machinery/shieldwallgen/proc/try_link_generators(direction)
+ var/turf/current_turf = loc
+ var/obj/machinery/shieldwallgen/other_generator
+ var/list/traveled_turfs = list()
+ for(var/distance in 1 to 9)
+ current_turf = get_step(current_turf, direction)
+ if(iswallturf(current_turf)) // Should go through windows etc
+ return
+ other_generator = locate(/obj/machinery/shieldwallgen) in current_turf
+ if(other_generator)
break
+ traveled_turfs += current_turf
- if(isnull(G))
+ if(!other_generator?.activated)
return
- T2 = loc
+ sleep(rand(1, 4)) // TODO check if we want this behaviour
- for(var/dist = 0, dist < steps, dist += 1) // creates each field tile
- var/field_dir = get_dir(T2,get_step(T2, NSEW))
- T = get_step(T2, NSEW)
- T2 = T
- var/obj/machinery/shieldwall/CF = new/obj/machinery/shieldwall/(src, G) //(ref to this gen, ref to connected gen)
- CF.loc = T
- CF.dir = field_dir
+ var/opposite_direction = turn(direction, 180)
+ for(var/T in traveled_turfs)
+ var/obj/machinery/shieldwall/SW = new /obj/machinery/shieldwall(T, src, other_generator) //(ref to this gen, ref to connected gen)
+ SW.dir = direction
+ active_shields["[direction]"] += SW
+ other_generator.active_shields["[opposite_direction]"] += SW
+/obj/machinery/shieldwallgen/proc/deactivate()
+ activated = FALSE
+ STOP_PROCESSING(SSmachines, src)
+ for(var/direction in GLOB.cardinal)
+ var/list/L = active_shields["[direction]"]
+ QDEL_LIST(L) // Don't want to clean the assoc keys so no QDEL_LIST_ASSOC_VAL
+
+/obj/machinery/shieldwallgen/proc/remove_active_shield(obj/machinery/shieldwall/SW, direction)
+ var/list/L = active_shields["[direction]"]
+ L -= SW
/obj/machinery/shieldwallgen/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/card/id)||istype(I, /obj/item/pda))
@@ -456,43 +431,20 @@
/obj/machinery/shieldwallgen/wrench_act(mob/user, obj/item/I)
. = TRUE
- if(active)
- to_chat(user, "Turn off the field generator first.")
+ if(activated)
+ to_chat(user, "Turn off the field generator first.")
return
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
- state = !state
anchored = !anchored
to_chat(user, anchored ? "You secure the external reinforcing bolts to the floor." : "You undo the external reinforcing bolts.")
-/obj/machinery/shieldwallgen/proc/cleanup(NSEW)
- var/obj/machinery/shieldwall/F
- var/obj/machinery/shieldwallgen/G
- var/turf/T = loc
- var/turf/T2 = loc
-
- for(var/dist = 0, dist <= 9, dist += 1) // checks out to 8 tiles away for fields
- T = get_step(T2, NSEW)
- T2 = T
- if(locate(/obj/machinery/shieldwall) in T)
- F = (locate(/obj/machinery/shieldwall) in T)
- if(F.gen_primary == src || F.gen_secondary == src)
- qdel(F)
-
- if(locate(/obj/machinery/shieldwallgen) in T)
- G = (locate(/obj/machinery/shieldwallgen) in T)
- if(!G.active)
- break
-
/obj/machinery/shieldwallgen/Destroy()
- cleanup(1)
- cleanup(2)
- cleanup(4)
- cleanup(8)
+ deactivate()
return ..()
/obj/machinery/shieldwallgen/bullet_act(obj/item/projectile/Proj)
- storedpower -= Proj.damage
+ stored_power -= Proj.damage
..()
return
@@ -513,13 +465,20 @@
var/obj/machinery/shieldwallgen/gen_primary
var/obj/machinery/shieldwallgen/gen_secondary
-/obj/machinery/shieldwall/New(obj/machinery/shieldwallgen/A, obj/machinery/shieldwallgen/B)
- ..()
+/obj/machinery/shieldwall/Initialize(mapload, obj/machinery/shieldwallgen/A, obj/machinery/shieldwallgen/B)
+ . = ..()
gen_primary = A
gen_secondary = B
if(A && B)
needs_power = TRUE
+/obj/machinery/shieldwall/Destroy()
+ gen_primary?.remove_active_shield(src, dir)
+ gen_secondary?.remove_active_shield(src, turn(dir, 180))
+ gen_primary = null
+ gen_secondary = null
+ return ..()
+
/obj/machinery/shieldwall/attack_hand(mob/user)
return
@@ -528,18 +487,10 @@
/obj/machinery/shieldwall/process()
if(needs_power)
- if(isnull(gen_primary)||isnull(gen_secondary))
- qdel(src)
- return
-
- if(!(gen_primary.active)||!(gen_secondary.active))
- qdel(src)
- return
-
if(prob(50))
- gen_primary.storedpower -= 10
+ gen_primary.stored_power = max(gen_primary.stored_power - 10, 0)
else
- gen_secondary.storedpower -=10
+ gen_secondary.stored_power = max(gen_secondary.stored_power - 10, 0)
/obj/machinery/shieldwall/bullet_act(obj/item/projectile/Proj)
@@ -549,7 +500,7 @@
G = gen_primary
else
G = gen_secondary
- G.storedpower -= Proj.damage
+ G.stored_power -= Proj.damage
..()
return
@@ -563,21 +514,21 @@
G = gen_primary
else
G = gen_secondary
- G.storedpower -= 200
+ G.stored_power -= 200
if(2.0) //medium boom
if(prob(50))
G = gen_primary
else
G = gen_secondary
- G.storedpower -= 50
+ G.stored_power -= 50
if(3.0) //lil boom
if(prob(50))
G = gen_primary
else
G = gen_secondary
- G.storedpower -= 20
+ G.stored_power -= 20
return
diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm
index a4c273ef6ef..b546c3a767e 100644
--- a/code/modules/power/singularity/singularity.dm
+++ b/code/modules/power/singularity/singularity.dm
@@ -371,7 +371,7 @@
return 0
else if(locate(/obj/machinery/shieldwallgen) in T)
var/obj/machinery/shieldwallgen/S = locate(/obj/machinery/shieldwallgen) in T
- if(S && S.active)
+ if(S?.activated)
return 0
return 1