From 0218b541f242edf9be80fb5975973e710f885b50 Mon Sep 17 00:00:00 2001
From: Migratingcocofruit
<69551563+Migratingcocofruit@users.noreply.github.com>
Date: Wed, 13 Nov 2024 15:23:41 +0200
Subject: [PATCH] Energy field generators Refactor/Tweak (#26919)
* Reduces range for energy seeking of generators, adds energy spreading and changes instances of power to energy. Containment field destructor no longer crashes when it has no connected generators
* review changes
* undef
* removes redundant line
* review changes
---
code/modules/admin/verbs/debug.dm | 2 +-
.../engines/singularity/containment_field.dm | 8 +-
.../engines/singularity/field_generator.dm | 103 ++++++++++--------
3 files changed, 64 insertions(+), 49 deletions(-)
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index c64f7dc8357..dccd9904032 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -726,7 +726,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
if(!F.active)
F.active = TRUE
F.state = 2
- F.power = 250
+ F.energy = 125
F.anchored = TRUE
F.warming_up = 3
F.start_fields()
diff --git a/code/modules/power/engines/singularity/containment_field.dm b/code/modules/power/engines/singularity/containment_field.dm
index e1c80554979..0c8f67e9c62 100644
--- a/code/modules/power/engines/singularity/containment_field.dm
+++ b/code/modules/power/engines/singularity/containment_field.dm
@@ -15,8 +15,10 @@
var/obj/machinery/field/generator/FG2 = null
/obj/machinery/field/containment/Destroy()
- FG1.fields -= src
- FG2.fields -= src
+ if(FG1)// These checks are mostly in case a field is spawned in by accident.
+ FG1.fields -= src
+ if(FG2)
+ FG2.fields -= src
return ..()
/obj/machinery/field/containment/attack_hand(mob/user)
@@ -50,7 +52,7 @@
return
if(ismegafauna(M))
M.visible_message("[M] glows fiercely as the containment field flickers out!")
- FG1.calc_power(INFINITY) //rip that 'containment' field
+ FG1.calc_energy(INFINITY) //rip that 'containment' field
M.adjustHealth(-M.obj_damage)
else
..()
diff --git a/code/modules/power/engines/singularity/field_generator.dm b/code/modules/power/engines/singularity/field_generator.dm
index c7238b8bdda..3d8a54279d1 100644
--- a/code/modules/power/engines/singularity/field_generator.dm
+++ b/code/modules/power/engines/singularity/field_generator.dm
@@ -1,14 +1,14 @@
/*
-field_generator power level display
- * The icon used for the field_generator need to have 'num_power_levels' number of icon states
- * named 'Field_Gen +p[num]' where 'num' ranges from 1 to 'num_power_levels'
- * The power level is displayed using overlays. The current displayed power level is stored in 'powerlevel'.
- * The overlay in use and the powerlevel variable must be kept in sync. A powerlevel equal to 0 means that
- * no power level overlay is currently in the overlays list.
+field_generator energy level display
+ * The icon used for the field_generator need to have 'num_energy_levels' number of icon states
+ * named 'Field_Gen +p[num]' where 'num' ranges from 1 to 'num_energy_levels'
+ * The energy level is displayed using overlays. The current displayed energy level is stored in 'energylevel'.
+ * The overlay in use and the energylevel variable must be kept in sync. A energylevel equal to 0 means that
+ * no energy level overlay is currently in the overlays list.
* -Aygar
*/
-#define field_generator_max_power 250
+#define FIELD_GENERATOR_MAX_ENERGY 125
#define FG_UNSECURED 0
#define FG_SECURED 1
@@ -31,10 +31,10 @@ GLOBAL_LIST_EMPTY(field_generator_fields)
max_integrity = 500
//100% immune to lasers and energy projectiles since it absorbs their energy.
armor = list(MELEE = 25, BULLET = 10, LASER = 100, ENERGY = 100, BOMB = 0, RAD = 0, FIRE = 50, ACID = 70)
- var/const/num_power_levels = 6 // Total number of power level icon has
- var/power_level = 0
+ var/const/num_energy_levels = 6 // Total number of power level icon has
+ var/energy_level = 0
var/active = FG_OFFLINE
- var/power = 20 // Current amount of power
+ var/energy = 20 // Current amount of energy
var/state = FG_UNSECURED
var/warming_up = 0
var/list/obj/machinery/field/containment/fields
@@ -47,8 +47,8 @@ GLOBAL_LIST_EMPTY(field_generator_fields)
. += "+a[warming_up]"
if(length(fields))
. += "+on"
- if(power_level)
- . += "+p[power_level]"
+ if(energy_level)
+ . += "+p[energy_level]"
/obj/machinery/field/generator/Initialize(mapload)
. = ..()
@@ -58,7 +58,7 @@ GLOBAL_LIST_EMPTY(field_generator_fields)
/obj/machinery/field/generator/process()
if(active == FG_ONLINE)
- calc_power()
+ calc_energy()
/obj/machinery/field/generator/attack_hand(mob/user)
if(state == FG_WELDED)
@@ -141,8 +141,8 @@ GLOBAL_LIST_EMPTY(field_generator_fields)
/obj/machinery/field/generator/bullet_act(obj/item/projectile/Proj)
if(Proj.flag != BULLET && !Proj.nodamage)
- power = min(power + Proj.damage, field_generator_max_power)
- check_power_level()
+ energy = min(energy + Proj.damage, FIELD_GENERATOR_MAX_ENERGY)
+ check_energy_level()
return 0
@@ -151,10 +151,10 @@ GLOBAL_LIST_EMPTY(field_generator_fields)
return ..()
-/obj/machinery/field/generator/proc/check_power_level()
- var/new_level = round(num_power_levels * power / field_generator_max_power)
- if(new_level != power_level)
- power_level = new_level
+/obj/machinery/field/generator/proc/check_energy_level()
+ var/new_level = round(num_energy_levels * energy / FIELD_GENERATOR_MAX_ENERGY)
+ if(new_level != energy_level)
+ energy_level = new_level
update_icon()
/obj/machinery/field/generator/proc/turn_off()
@@ -177,49 +177,60 @@ GLOBAL_LIST_EMPTY(field_generator_fields)
start_fields()
-/obj/machinery/field/generator/proc/calc_power()
+/obj/machinery/field/generator/proc/calc_energy()
var/power_draw = 2 + length(fields)
- if(draw_power(round(power_draw/2, 1)))
- check_power_level()
- return 1
+ if(draw_power(round(power_draw / 2, 1)))
+ spread_energy()
+ check_energy_level()
+ return TRUE
else
visible_message("[src] shuts down!", "You hear something shutting down.")
turn_off()
- investigate_log("ran out of power and deactivated","singulo")
- power = 0
- check_power_level()
- return 0
+ investigate_log("ran out of energy and deactivated","singulo")
+ energy = 0
+ check_energy_level()
+ return FALSE
-//This could likely be better, it tends to start loopin if you have a complex generator loop setup. Still works well enough to run the engine fields will likely recode the field gens and fields sometime -Mport
-/obj/machinery/field/generator/proc/draw_power(draw = 0, failsafe = 0, obj/machinery/field/generator/G = null, obj/machinery/field/generator/last = null)
- if((G && (G == src)) || (failsafe >= 8))//Loopin, set fail
+/**
+* Draws power. If there isn't enough energy to sustain the draw, draw from connected generators, up to 3 generators away.
+* We never do a 180, so at most we should be going around 270 degrees, and never loop.
+*
+* Arguments:
+** draw - Amount of energy needed to sustain powerdraw during this cycle
+** failsafe - Current depth of the recursion. We don't let this go above 3.
+** last - should be src of the previous call, we check against this to prevent going back and forth between two field generators.
+*/
+/obj/machinery/field/generator/proc/draw_power(draw = 0, failsafe = 0, obj/machinery/field/generator/last = null)
+ if(failsafe >= 3)// Asking at most 3 gens away so we can't loop.
return 0
else
failsafe++
- if(power >= draw)//We have enough power
- power -= draw
+ if(energy >= draw)// We have enough energy
+ energy -= draw
return 1
- else//Need more power
- draw -= power
- power = 0
+ else//Need more energy
+ draw -= energy
+ energy = 0
for(var/CG in connected_gens)
var/obj/machinery/field/generator/FG = CG
- if(FG == last)//We just asked you
+ if(FG == last)// We just asked you
continue
- if(G)//Another gen is askin for power and we dont have it
- if(FG.draw_power(draw,failsafe,G,src))//Can you take the load
- return 1
- else
- return 0
- else//We are askin another for power
- if(FG.draw_power(draw,failsafe,src,src))
+ else// We are askin another for energy
+ if(FG.draw_power(draw, failsafe, src))
return 1
else
return 0
+/// Sends energy to every neighbour that has less energy
+/obj/machinery/field/generator/proc/spread_energy()
+ for(var/obj/machinery/field/generator/gen as anything in connected_gens)
+ if(energy > gen.energy + 3)
+ var/diff = min(energy - gen.energy, FIELD_GENERATOR_MAX_ENERGY - gen.energy)// We don't want to delete energy
+ gen.energy += diff / 2
+ energy -= diff / 2
/obj/machinery/field/generator/proc/start_fields()
if(state != FG_WELDED || !anchored)
@@ -299,8 +310,8 @@ GLOBAL_LIST_EMPTY(field_generator_fields)
for(var/CG in connected_gens)
var/obj/machinery/field/generator/FG = CG
FG.connected_gens -= src
- if(!FG.clean_up)//Makes the other gens clean up as well
- FG.cleanup()
+ if(!FG.clean_up)//Makes the other gens clean up and shutdown as well
+ FG.turn_off()
connected_gens -= FG
clean_up = FALSE
update_icon()
@@ -343,3 +354,5 @@ GLOBAL_LIST_EMPTY(field_generator_fields)
#undef FG_OFFLINE
#undef FG_CHARGING
#undef FG_ONLINE
+
+#undef FIELD_GENERATOR_MAX_ENERGY