mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2025-12-20 15:21:29 +00:00
* local powernet and machine power refactor * some fixes * more tweaks + powerchange() refactor * fixes var edited apcs on meatpackers.dmm * fixes issue with power channels * Reviews * delta fix * Update code/game/machinery/portable_turret.dm Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com> * removed area power change proc * damn morgues * requested changes * request changes * deconfliction * mapping fixes * some fixes from TM --------- Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com>
189 lines
7.6 KiB
Plaintext
189 lines
7.6 KiB
Plaintext
/**
|
|
* # local_powernet
|
|
*
|
|
* Manages all power related mechanics for a single /area
|
|
* Machines in areas will directly register to this datum in order to recieve power
|
|
*
|
|
* Machine/Turf/Item -> Local Powernet -> APC -> Terminal -> Wirenet
|
|
*
|
|
* Non-machines cannot register to the local powernet and should instead listen for power change signals
|
|
*/
|
|
/datum/local_powernet
|
|
/// The area this local powernet is attached to
|
|
var/area/powernet_area = null
|
|
/// The APC associated with this powernet
|
|
var/obj/machinery/power/apc/powernet_apc = null
|
|
|
|
/// Bit Flags indicating special behaviour on this powernet, always powered, never powered, etc
|
|
var/power_flags
|
|
|
|
/// Is the equipment power channel on?
|
|
var/equipment_powered = TRUE
|
|
/// Is the lighting power channel on?
|
|
var/lighting_powered = TRUE
|
|
/// Is the environment power channel on?
|
|
var/environment_powered = TRUE
|
|
|
|
/* Passive consumption vars, only change when machines are added/removed from the powernet (not if the power channel turns on/off) */
|
|
/// The amount of power consumed by equipment in every power cycle
|
|
var/passive_equipment_consumption = 0
|
|
/// The amount of power consumed by lighting in every power cycle
|
|
var/passive_lighting_consumption = 0
|
|
/// The amount of power consumed by environment in every power cycle
|
|
var/passive_environment_consumption = 0
|
|
|
|
/* Active consumption vars, changed when machines need spurts of power, unlike passive consumption these reset to 0 every process() cycle */
|
|
/// The amount of power consumed by equipment in this power cycle
|
|
var/equipment_consumption = 0
|
|
/// The amount of power consumed by lighting in this power cycle
|
|
var/lighting_consumption = 0
|
|
/// The amount of power consumed by environment in this power cycle
|
|
var/environment_consumption = 0
|
|
|
|
/* Total consumption vars, tracking vars that only count aggregate consumption from active power channels */
|
|
/// The amount of the total power consumed passively in power cycles (i.e, each cycle), does not include power channels that are off
|
|
var/passive_consumption = 0
|
|
/// The amount of total power consumed consumed in only this cycle
|
|
var/active_consumption = 0
|
|
|
|
/// All machines registered to this local powernet, strictly typed to machines, everything else needs to register power change signals
|
|
var/list/registered_machines = list()
|
|
|
|
/// tethers a machine to this local powernet
|
|
/datum/local_powernet/proc/register_machine(obj/machinery/machine)
|
|
if(machine in registered_machines)
|
|
machine.power_change() // this is probably what they wanted anyway by calling this proc
|
|
log_debug("[machine] try to register to [powernet_apc]'s local powernet but was already registered!")
|
|
return
|
|
// machines ref'd in this list should clear themselves from it in destroy(), no need for signals here
|
|
machine.machine_powernet = src
|
|
registered_machines += machine
|
|
machine.power_change()
|
|
|
|
/// untethers a machine to this local powernet
|
|
/datum/local_powernet/proc/unregister_machine(obj/machinery/machine)
|
|
if(!(machine in registered_machines))
|
|
return
|
|
machine.machine_powernet = null
|
|
registered_machines -= machine
|
|
machine.power_change()
|
|
|
|
/**
|
|
* # power_change
|
|
*
|
|
* Called when the area power status changes
|
|
* calls power change on all machines in the area, and sends the `COMSIG_POWERNET_POWER_CHANGE` signal.
|
|
*/
|
|
/datum/local_powernet/proc/power_change()
|
|
for(var/obj/machinery/M as anything in registered_machines) // for each machine in the area
|
|
M.power_change() // reverify power status (to update icons etc.)
|
|
SEND_SIGNAL(src, COMSIG_POWERNET_POWER_CHANGE)
|
|
|
|
/// sets a power channel on or off and adjusts total power usage accordingly
|
|
/datum/local_powernet/proc/set_power_channel(channel, new_state)
|
|
switch(channel)
|
|
if(PW_CHANNEL_EQUIPMENT)
|
|
if(equipment_powered == new_state)
|
|
return
|
|
passive_consumption += (passive_equipment_consumption * (new_state ? 1 : -1))
|
|
equipment_powered = new_state
|
|
if(PW_CHANNEL_LIGHTING)
|
|
if(lighting_powered == new_state)
|
|
return
|
|
passive_consumption += (passive_lighting_consumption * (new_state ? 1 : -1))
|
|
lighting_powered = new_state
|
|
if(PW_CHANNEL_ENVIRONMENT)
|
|
if(environment_powered == new_state)
|
|
return
|
|
passive_consumption += (passive_environment_consumption * (new_state ? 1 : -1))
|
|
environment_powered = new_state
|
|
power_change()
|
|
|
|
/// checks to see if the given channel in this local powernet has power
|
|
/datum/local_powernet/proc/has_power(channel)
|
|
if(power_flags & PW_ALWAYS_UNPOWERED) //if this local powernet can never be powered, always return FALSE
|
|
return FALSE
|
|
if(power_flags & PW_ALWAYS_POWERED) //if this powernet is always powered, we always return TRUE
|
|
return TRUE
|
|
if(powernet_apc?.stat & (BROKEN|MAINT)) //no working apc, no power
|
|
return FALSE
|
|
|
|
switch(channel)
|
|
if(PW_CHANNEL_EQUIPMENT)
|
|
return equipment_powered
|
|
if(PW_CHANNEL_LIGHTING)
|
|
return lighting_powered
|
|
if(PW_CHANNEL_ENVIRONMENT)
|
|
return environment_powered
|
|
return FALSE
|
|
|
|
/// Add active power usage to the given channel, returns FALSE is channel cannot be found or the channel does not have power to give
|
|
/datum/local_powernet/proc/use_active_power(channel, amount)
|
|
if(!has_power(channel))
|
|
return FALSE
|
|
if(power_flags & PW_ALWAYS_POWERED)
|
|
return TRUE //we check here as well because we want to skip calculations if we will always have power
|
|
switch(channel)
|
|
if(PW_CHANNEL_EQUIPMENT)
|
|
equipment_consumption += amount
|
|
if(PW_CHANNEL_LIGHTING)
|
|
lighting_consumption += amount
|
|
if(PW_CHANNEL_ENVIRONMENT)
|
|
environment_consumption += amount
|
|
else
|
|
return FALSE
|
|
active_consumption += amount
|
|
return TRUE
|
|
|
|
/// Adjust static power for a specified channel, does not check to see if channel has power flowing into it
|
|
/datum/local_powernet/proc/adjust_static_power(channel, amount)
|
|
if(power_flags & PW_ALWAYS_POWERED)
|
|
return TRUE //we check here as well because we want to skip calculations if we will always have power
|
|
switch(channel)
|
|
if(PW_CHANNEL_EQUIPMENT)
|
|
passive_equipment_consumption += amount
|
|
if(PW_CHANNEL_LIGHTING)
|
|
passive_lighting_consumption += amount
|
|
if(PW_CHANNEL_ENVIRONMENT)
|
|
passive_environment_consumption += amount
|
|
else
|
|
return FALSE
|
|
if(has_power(channel)) // our total consumption vars don't track unpowered channels, so don't change the var if there's no power
|
|
passive_consumption += amount
|
|
return TRUE
|
|
|
|
/datum/local_powernet/proc/get_total_usage()
|
|
return passive_consumption + active_consumption
|
|
|
|
/// returns active + passive power of a channel, if the channel is not powered it returns 0 watts
|
|
/datum/local_powernet/proc/get_channel_usage(channel)
|
|
switch(channel)
|
|
if(PW_CHANNEL_EQUIPMENT)
|
|
return equipment_powered ? passive_equipment_consumption + equipment_consumption : 0
|
|
if(PW_CHANNEL_LIGHTING)
|
|
return lighting_powered ? passive_lighting_consumption + lighting_consumption : 0
|
|
if(PW_CHANNEL_ENVIRONMENT)
|
|
return environment_powered ? passive_environment_consumption + environment_consumption : 0
|
|
|
|
/datum/local_powernet/proc/clear_usage()
|
|
equipment_consumption = 0
|
|
lighting_consumption = 0
|
|
environment_consumption = 0
|
|
active_consumption = 0
|
|
|
|
/// Handles flicker operations for apc processing, will flicker machines and lights in the powernet's area by random chance
|
|
/datum/local_powernet/proc/handle_flicker()
|
|
if(prob(MACHINE_FLICKER_CHANCE))
|
|
powernet_apc?.flicker()
|
|
|
|
// lights don't have their own processing loop, so local powernets will be the father they never had. 3x as likely to cause a light flicker in a particular area, pick a light to flicker at random
|
|
if(prob(MACHINE_FLICKER_CHANCE * 3))
|
|
var/list/lights = list()
|
|
for(var/obj/machinery/light/L in powernet_area)
|
|
lights += L
|
|
|
|
if(length(lights))
|
|
var/obj/machinery/light/picked_light = pick(lights)
|
|
ASSERT(istype(picked_light))
|
|
picked_light.flicker()
|