From 3dc47a125d468baf202e9c849b863fda35d4e001 Mon Sep 17 00:00:00 2001 From: Farie82 Date: Mon, 15 Aug 2022 21:29:21 +0200 Subject: [PATCH] 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 --- .../RandomRuins/SpaceRuins/abandonedzoo.dmm | 40 ++- code/game/machinery/shieldgen.dm | 241 +++++++----------- code/modules/power/singularity/singularity.dm | 2 +- 3 files changed, 113 insertions(+), 170 deletions(-) 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