mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 02:09:41 +00:00
Co-authored-by: Heroman3003 <31296024+Heroman3003@users.noreply.github.com> Co-authored-by: BlackMajor <henrydyer6@hotmail.com>
195 lines
6.3 KiB
Plaintext
195 lines
6.3 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/viewavail = 0 // the availability as it appears on the power console (gradually updated)
|
|
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()
|
|
START_PROCESSING_POWERNET(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
|
|
STOP_PROCESSING_POWERNET(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/terminal/T in inputting)
|
|
var/obj/machinery/power/smes/S = T.master
|
|
if(istype(S))
|
|
S.input_power(smes_input_percentage, T)
|
|
|
|
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)
|
|
viewavail = round(0.8 * viewavail + 0.2 * avail)
|
|
viewload = round(0.8 * viewload + 0.2 * 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, (load / avail) * 100, 100)
|
|
|
|
/datum/powernet/proc/get_electrocute_damage()
|
|
//1kW = 5
|
|
//10kW = 24
|
|
//100kW = 45
|
|
//250kW = 53
|
|
//1MW = 66
|
|
//10MW = 88
|
|
//100MW = 110
|
|
//1GW = 132
|
|
if(avail >= 1000)
|
|
var/damage = log(1.1,avail)
|
|
damage = damage - (log(1.1,damage)*1.5)
|
|
return round(damage)
|
|
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/floor)) //VOREStation Removal - Why?
|
|
//return null //VOREStation Removal - Why?
|
|
for(var/obj/structure/cable/C in src)
|
|
if(C.d1 == 0)
|
|
return C
|
|
return null
|
|
|
|
|
|
/area/proc/get_apc()
|
|
return apc
|