mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-21 15:42:35 +00:00
changes: Airlocks no longer tick (exceptions: firedoors, uranium airlocks) Airlock commands run before round-start are queued to run at round-start. Airlock commands that failed to run are scheduled to try again in 2 seconds with timers. Callbacks can now be registered with SSticker to run at round-start in a non-blocking way. Added a new subsystem (SSpower) for handling power-related functions. Currently doesn't do a whole lot, but this will likely eventually change. RCON functionality has been moved from SSmachinery to SSpower. The global cable list has been moved into SSpower. Powernet sensors no longer process purely to keep themselves in the global machines list, instead they are added to a list in SSpower. Power terminals no longer pointlessly tick. Removed some variables from SSticker that weren't used by anything. Holographic overlays such as those used by consoles are now cached. Xenoarcheology setup is now tick-checked. ZAS now uses post-fire timing. The req_access and req_one_access lists are no longer initialized by default on all /obj types. Openturfs will only emit starlight if they are bordering a non-openturf dynamically lit turf. Powernets are now stored in SSpower instead of being a global. The global mouse list is now stored in SSmob instead of being a global. Fixed some weirdness in APCs' Destroy() caused by a merge. SSwireless now pre-bakes to reduce round-start processing. SSwireless no longer uses processing queues.
191 lines
6.1 KiB
Plaintext
191 lines
6.1 KiB
Plaintext
/datum/powernet
|
|
var/list/cables = list() // all cables & junctions
|
|
var/list/nodes = list() // all connected machines
|
|
|
|
var/load = 0 // the current load on the powernet, increased by each machine at processing
|
|
var/newavail = 0 // what available power was gathered last tick, then becomes...
|
|
var/avail = 0 //...the current available power in the powernet
|
|
var/viewload = 0 // the load as it appears on the power console (gradually updated)
|
|
var/number = 0 // Unused //TODEL
|
|
|
|
var/smes_demand = 0 // Amount of power demanded by all SMESs from this network. Needed for load balancing.
|
|
var/list/inputting = list() // List of SMESs that are demanding power from this network. Needed for load balancing.
|
|
|
|
var/smes_avail = 0 // Amount of power (avail) from SMESes. Used by SMES load balancing
|
|
var/smes_newavail = 0 // As above, just for newavail
|
|
|
|
var/perapc = 0 // per-apc avilability
|
|
var/perapc_excess = 0
|
|
var/netexcess = 0 // excess power on the powernet (typically avail-load)
|
|
|
|
var/problem = 0 // If this is not 0 there is some sort of issue in the powernet. Monitors will display warnings.
|
|
|
|
/datum/powernet/New()
|
|
SSpower.powernets += src
|
|
..()
|
|
|
|
/datum/powernet/Destroy()
|
|
for(var/obj/structure/cable/C in cables)
|
|
cables -= C
|
|
C.powernet = null
|
|
for(var/obj/machinery/power/M in nodes)
|
|
nodes -= M
|
|
M.powernet = null
|
|
SSpower.powernets -= src
|
|
return ..()
|
|
|
|
//Returns the amount of excess power (before refunding to SMESs) from last tick.
|
|
//This is for machines that might adjust their power consumption using this data.
|
|
/datum/powernet/proc/last_surplus()
|
|
return max(avail - load, 0)
|
|
|
|
/datum/powernet/proc/draw_power(var/amount)
|
|
var/draw = between(0, amount, avail - load)
|
|
load += draw
|
|
return draw
|
|
|
|
/datum/powernet/proc/is_empty()
|
|
return !cables.len && !nodes.len
|
|
|
|
//remove a cable from the current powernet
|
|
//if the powernet is then empty, delete it
|
|
//Warning : this proc DON'T check if the cable exists
|
|
/datum/powernet/proc/remove_cable(var/obj/structure/cable/C)
|
|
cables -= C
|
|
C.powernet = null
|
|
if(is_empty())//the powernet is now empty...
|
|
qdel(src)///... delete it
|
|
|
|
//add a cable to the current powernet
|
|
//Warning : this proc DON'T check if the cable exists
|
|
/datum/powernet/proc/add_cable(var/obj/structure/cable/C)
|
|
if(C.powernet)// if C already has a powernet...
|
|
if(C.powernet == src)
|
|
return
|
|
else
|
|
C.powernet.remove_cable(C) //..remove it
|
|
C.powernet = src
|
|
cables +=C
|
|
|
|
//remove a power machine from the current powernet
|
|
//if the powernet is then empty, delete it
|
|
//Warning : this proc DON'T check if the machine exists
|
|
/datum/powernet/proc/remove_machine(var/obj/machinery/power/M)
|
|
nodes -=M
|
|
M.powernet = null
|
|
if(is_empty())//the powernet is now empty...
|
|
qdel(src)///... delete it - qdel
|
|
|
|
|
|
//add a power machine to the current powernet
|
|
//Warning : this proc DON'T check if the machine exists
|
|
/datum/powernet/proc/add_machine(var/obj/machinery/power/M)
|
|
if(M.powernet)// if M already has a powernet...
|
|
if(M.powernet == src)
|
|
return
|
|
else
|
|
M.disconnect_from_network()//..remove it
|
|
M.powernet = src
|
|
nodes[M] = M
|
|
|
|
// Triggers warning for certain amount of ticks
|
|
/datum/powernet/proc/trigger_warning(var/duration_ticks = 20)
|
|
problem = max(duration_ticks, problem)
|
|
|
|
|
|
//handles the power changes in the powernet
|
|
//called every ticks by the powernet controller
|
|
/datum/powernet/proc/reset()
|
|
var/numapc = 0
|
|
|
|
if(problem > 0)
|
|
problem = max(problem - 1, 0)
|
|
|
|
if(nodes && nodes.len) // Added to fix a bad list bug -- TLE
|
|
for(var/obj/machinery/power/terminal/term in nodes)
|
|
if( istype( term.master, /obj/machinery/power/apc ) )
|
|
numapc++
|
|
|
|
netexcess = avail - load
|
|
|
|
if(numapc)
|
|
//very simple load balancing. If there was a net excess this tick then it must have been that some APCs used less than perapc, since perapc*numapc = avail
|
|
//Therefore we can raise the amount of power rationed out to APCs on the assumption that those APCs that used less than perapc will continue to do so.
|
|
//If that assumption fails, then some APCs will miss out on power next tick, however it will be rebalanced for the tick after.
|
|
if (netexcess >= 0)
|
|
perapc_excess += min(netexcess/numapc, (avail - perapc) - perapc_excess)
|
|
else
|
|
perapc_excess = 0
|
|
|
|
perapc = avail/numapc + perapc_excess
|
|
|
|
// At this point, all other machines have finished using power. Anything left over may be used up to charge SMESs.
|
|
if(inputting.len && smes_demand)
|
|
var/smes_input_percentage = between(0, (netexcess / smes_demand) * 100, 100)
|
|
for(var/obj/machinery/power/smes/S in inputting)
|
|
S.input_power(smes_input_percentage)
|
|
|
|
netexcess = avail - load
|
|
|
|
if(netexcess)
|
|
var/perc = get_percent_load(1)
|
|
for(var/obj/machinery/power/smes/S in nodes)
|
|
S.restore(perc)
|
|
|
|
//updates the viewed load (as seen on power computers)
|
|
viewload = round(load)
|
|
|
|
//reset the powernet
|
|
load = 0
|
|
avail = newavail
|
|
smes_avail = smes_newavail
|
|
inputting.Cut()
|
|
smes_demand = 0
|
|
newavail = 0
|
|
smes_newavail = 0
|
|
|
|
/datum/powernet/proc/get_percent_load(var/smes_only = 0)
|
|
if(smes_only)
|
|
var/smes_used = load - (avail - smes_avail) // SMESs are always last to provide power
|
|
if(!smes_used || smes_used < 0 || !smes_avail) // SMES power isn't available or being used at all, SMES load is therefore 0%
|
|
return 0
|
|
return between(0, (smes_used / smes_avail) * 100, 100) // Otherwise return percentage load of SMESs.
|
|
else
|
|
if(!load)
|
|
return 0
|
|
return between(0, (avail / load) * 100, 100)
|
|
|
|
/datum/powernet/proc/get_electrocute_damage()
|
|
switch(avail)
|
|
if (1000000 to INFINITY)
|
|
return min(rand(50,160),rand(50,160))
|
|
if (200000 to 1000000)
|
|
return min(rand(25,80),rand(25,80))
|
|
if (100000 to 200000)//Ave powernet
|
|
return min(rand(20,60),rand(20,60))
|
|
if (50000 to 100000)
|
|
return min(rand(15,40),rand(15,40))
|
|
if (1000 to 50000)
|
|
return min(rand(10,20),rand(10,20))
|
|
else
|
|
return 0
|
|
|
|
////////////////////////////////////////////////
|
|
// Misc.
|
|
///////////////////////////////////////////////
|
|
|
|
|
|
// return a knot cable (O-X) if one is present in the turf
|
|
// null if there's none
|
|
/turf/proc/get_cable_node()
|
|
if(!istype(src, /turf/simulated))
|
|
return null
|
|
for(var/obj/structure/cable/C in src)
|
|
if(C.d1 == 0)
|
|
return C
|
|
return null
|
|
|
|
|
|
/area/proc/get_apc()
|
|
return apc
|