Files
Paradise/code/modules/power/powernets/regional_powernet.dm
Ryan 11717823df Power Code Cleanup + Conversion to Regional Powernets [Refactor Only] (#20598)
* initial edits

* more cleanup, yipee

* moving shit around

* dme fixes

* fixes file ticking issue

* more dme fixes + duplicate files???

* Apply suggestions from code review

Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com>

* glass floor fixes

* Apply suggestions from code review

Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com>

* requested reviews

* the most painful bugfix of my life

* forgot to remove some debug stuff

* fixed issues with excess power

* fuck powernets (fix)

* Update code/modules/power/powernets/README.md

Co-authored-by: SteelSlayer <42044220+SteelSlayer@users.noreply.github.com>

---------

Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com>
Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com>
Co-authored-by: SteelSlayer <42044220+SteelSlayer@users.noreply.github.com>
2023-05-31 20:55:10 -05:00

136 lines
5.0 KiB
Plaintext

/*
* # /datum/regional_powernet
*
* each contiguous network of cables & nodes over a large area, unlike local powernets, these powernets
* don't concern areas and are instead attached to a single wirenet with power machine, engine, battery, and terminal nodes
*/
/datum/regional_powernet
/// The Powernet Unique ID Number
var/number
/// A list of All cables & junctions in this powernet
var/list/cables = list()
/// All Power Machines that are connected to this powernet
var/list/nodes = list()
/// the current available power in the powernet
var/available_power = 0
/// the current load on the powernet, increased by each machine at processing
var/power_demand = 0
/// what available power was gathered last tick, then becomes...
var/queued_power_production = 0
/// load applied to powernet between power ticks.
var/queued_power_demand = 0
/// excess power on the powernet (typically avail-load)
var/excess_power = 0
/// the available power as it appears on the power console (gradually updated)
var/smoothed_available_power = 0
/// the load as it appears on the power console (gradually updated)
var/smoothed_demand = 0
/datum/regional_powernet/New()
. = ..()
SSmachines.powernets += src
/datum/regional_powernet/Destroy()
//Go away references, you suck!
for(var/obj/structure/cable/C as anything in cables)
cables -= C
C.powernet = null
for(var/obj/machinery/power/M as anything in nodes)
nodes -= M
M.powernet = null
SSmachines.powernets -= src
return ..()
/datum/regional_powernet/proc/is_empty()
return !length(cables) && !length(nodes)
/// remove a cable from the current powernet, if the powernet is empty after, delete it
/datum/regional_powernet/proc/remove_cable(obj/structure/cable/C)
cables -= C
C.powernet = null
if(is_empty())
qdel(src) //powernet datums are useless if they have no nodes/cables
/// add a cable to the current powernet
/datum/regional_powernet/proc/add_cable(obj/structure/cable/C)
if(C.powernet)
if(C.powernet != src)
C.powernet.remove_cable(C) //if C already has a powernet remove it
else
return //already connect to this powernet, return
C.powernet = src
cables += C
/// remove a power machine from the current powernet, if the powernet is then empty, delete it
/datum/regional_powernet/proc/remove_machine(obj/machinery/power/M)
nodes -= M
M.powernet = null
if(is_empty()) //the powernet is now empty so delete it
qdel(src)
/// add a power machine to the current powernet
/datum/regional_powernet/proc/add_machine(obj/machinery/power/M)
if(M.powernet)
if(M.powernet != src)
M.disconnect_from_network() // if M already has a powernet disconnect it from old powernet
else
return // already connected to this powernet, return
M.powernet = src
nodes[M] = M
/// Returns the clamped difference between available power on the net and the demanded power, i.g. the surplus power available
/datum/regional_powernet/proc/calculate_surplus()
return clamp(available_power - power_demand, 0, available_power)
/// Returns the non-clamped difference between available power on the net and the demanded power, i.g. consumption vs. supply
/datum/regional_powernet/proc/calculate_power_balance()
return (available_power - power_demand)
/datum/regional_powernet/proc/calculate_queued_surplus()
return clamp(queued_power_production - queued_power_demand, 0, queued_power_production)
/*
* # process_power()
*
* Bread and butter of the regional powernet datum, handles calculatting excess power in the net
* and returns that excess to connected batteries. Furthermore, will clear/apply the previous usage and take
* the new usage from the next tick after and apply it to the current power tracking vars
*
* called every tick by the powernet controller
*/
/datum/regional_powernet/proc/process_power()
//Calculate excess power in the net, so the difference between how much is used vs. how much is sent into the powernet
excess_power = calculate_surplus()
if(excess_power > 100 && length(nodes))
for(var/obj/machinery/power/smes/S in nodes) // find the SMESes in the network
S.restore() // and restore some of the power that was used
// update power consoles, the reason we use 80% old value and 20% new value is to give the illusion of smoothness
smoothed_available_power = round(0.8 * smoothed_available_power + 0.2 * available_power)
smoothed_demand = round(0.8 * smoothed_demand + 0.2 * power_demand)
// reset the powernet
power_demand = queued_power_demand
queued_power_demand = 0
available_power = queued_power_production
queued_power_production = 0
#define MINIMUM_PW_SHOCK 1000
#define MINIMUM_SHOCK_DAMAGE 20
#define MAXIMUM_SHOCK_DAMAGE 195
#define WATT_TO_DAMAGE_RATIO 25000
/datum/regional_powernet/proc/get_electrocute_damage()
if(available_power >= MINIMUM_PW_SHOCK)
return clamp(MINIMUM_SHOCK_DAMAGE + round(available_power / WATT_TO_DAMAGE_RATIO), MINIMUM_SHOCK_DAMAGE, MAXIMUM_SHOCK_DAMAGE) + rand(-5, 5)
else
return 0
#undef MINIMUM_PW_SHOCK
#undef MINIMUM_SHOCK_DAMAGE
#undef MAXIMUM_SHOCK_DAMAGE
#undef WATT_TO_DAMAGE_RATIO