Makes shieldwall generators actually work and not drain the CPU (#18613)

* Fixes shieldwallgen's
Also makes them not suck performance like hell

* Update code/modules/power/singularity/singularity.dm

* Update code/modules/power/singularity/singularity.dm

* Makes walls stop the shieldwallgen from making walls

* Review changes
Make shieldgen not process when inactive
This commit is contained in:
Farie82
2022-08-15 21:29:21 +02:00
committed by GitHub
parent 79139cc0a8
commit 3dc47a125d
3 changed files with 113 additions and 170 deletions
@@ -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;
+96 -145
View File
@@ -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, "<span class='warning'>The shield generator needs to be firmly secured to the floor first.</span>")
return TRUE
if(locked && !issilicon(user))
to_chat(user, "<span class='warning'>The controls are locked!</span>")
return TRUE
if(!power)
var/turf/T = loc
if(!T.get_cable_node())
to_chat(user, "<span class='warning'>The shield generator needs to be powered by wire underneath.</span>")
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("<span class='notice'>[user] turned the shield generator [activated ? "on" : "off"].</span>", \
"<span class='notice'>You turn [activated ? "on" : "off"] the shield generator.</span>", \
"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("<span class='warning'>[name] shuts down due to lack of power!</span>", \
if(!try_charge_shields_power())
visible_message("<span class='warning'>[name] shuts down due to lack of power!</span>", \
"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, "<span class='warning'>Turn off the field generator first.</span>")
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
@@ -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