[MIRROR] large refactor of machine/power code to cut down on processing time and wasted lists (#7920)

* large refactor of machine/power code to cut down on processing time and wasted lists (#60317)

original pr here: #59789 (Closed because he didn't think it was good enough)
came back to this because i realized that

    all machines were area sensitive, meaning they had a list with at least a reference to themselves (assuming they arent in the contents of another movable which most arent) for the purposes of handling power differences when their area changes
    pipes are machines
    there are ~14k machines and ~6k pipes
    i made this problem worse with a recent pr by making it a nested list

so i needed to track what machines needed power, and this pr had work already done that could be used for that purpose. now machines that have use_power == NO_POWER_USE do not have this extra memory overhead for no reason

currently every machine that uses power draws that amount from its area from a dynamic channel via auto_use_power() which is called every SSmachines fire(), then in apc/process() the area's dynamic power draw is reset and the power is used. with static power its not calculated then reset every loop, its just taken from the grid. so now machines handle updating their static power usage from their current area (this doesnt touch power machines that require a wire connection). in order to allow this, use_power, idle_power_usage, and active_power_usage have setters to track state correctly and update the static power usage on the machines current area and handle area sensitivity.

also goes through a lot of heavy abusers of SSmachine processing time and tries to make it faster. makes airalarm/process() into a signal handler for COMSIG_TURF_EXPOSE since air alarms only need to process for changes.
Why It's Good For The Game

SSmachines isnt the heaviest hitter in terms of total cpu and certainly not in terms of overtime, but its not a lightweight. it frequently takes > 50ms to complete a run and seems to be in the top 5 or so of subsystem costs looking at some round profilers

also gets rid of a few thousand lists since every pipe no longer has two useless lists each (and any other machines that dont use power)

Love ya kyler

Co-authored-by: Rohesie <rohesie@ gmail.com>

* large refactor of machine/power code to cut down on processing time and wasted lists

Co-authored-by: Kylerace <kylerlumpkin1@gmail.com>
Co-authored-by: Rohesie <rohesie@ gmail.com>
This commit is contained in:
SkyratBot
2021-09-02 04:11:59 +02:00
committed by GitHub
parent d8e8493e85
commit a2aaacdead
37 changed files with 547 additions and 357 deletions

View File

@@ -7,15 +7,20 @@
#define AREA_USAGE_STATIC_LIGHT 5 #define AREA_USAGE_STATIC_LIGHT 5
#define AREA_USAGE_STATIC_ENVIRON 6 #define AREA_USAGE_STATIC_ENVIRON 6
#define AREA_USAGE_LEN AREA_USAGE_STATIC_ENVIRON // largest idx #define AREA_USAGE_LEN AREA_USAGE_STATIC_ENVIRON // largest idx
/// Index of the first dynamic usage channel /// Index of the first dynamic usage channel
#define AREA_USAGE_DYNAMIC_START AREA_USAGE_EQUIP #define AREA_USAGE_DYNAMIC_START AREA_USAGE_EQUIP
/// Index of the last dynamic usage channel /// Index of the last dynamic usage channel
#define AREA_USAGE_DYNAMIC_END AREA_USAGE_ENVIRON #define AREA_USAGE_DYNAMIC_END AREA_USAGE_ENVIRON
/// Index of the first static usage channel /// Index of the first static usage channel
#define AREA_USAGE_STATIC_START AREA_USAGE_STATIC_EQUIP #define AREA_USAGE_STATIC_START AREA_USAGE_STATIC_EQUIP
/// Index of the last static usage channel /// Index of the last static usage channel
#define AREA_USAGE_STATIC_END AREA_USAGE_STATIC_ENVIRON #define AREA_USAGE_STATIC_END AREA_USAGE_STATIC_ENVIRON
#define DYNAMIC_TO_STATIC_CHANNEL(dyn_channel) (dyn_channel + (AREA_USAGE_STATIC_START - AREA_USAGE_DYNAMIC_START))
#define STATIC_TO_DYNAMIC_CHANNEL(static_channel) (static_channel - (AREA_USAGE_STATIC_START - AREA_USAGE_DYNAMIC_START))
//Power use //Power use
#define NO_POWER_USE 0 #define NO_POWER_USE 0
@@ -196,3 +201,12 @@
#define AIRALARM_BUILD_NO_WIRES 1 #define AIRALARM_BUILD_NO_WIRES 1
/// Air alarm has all components but isn't completed /// Air alarm has all components but isn't completed
#define AIRALARM_BUILD_COMPLETE 2 #define AIRALARM_BUILD_COMPLETE 2
///TLV datums wont check limits set to this
#define TLV_DONT_CHECK -1
///the gas mixture is within the bounds of both warning and hazard limits
#define TLV_NO_DANGER 0
///the gas value is outside the warning limit but within the hazard limit, the air alarm will go into warning mode
#define TLV_OUTSIDE_WARNING_LIMIT 1
///the gas is outside the hazard limit, the air alarm will go into hazard mode
#define TLV_OUTSIDE_HAZARD_LIMIT 2

View File

@@ -13,25 +13,24 @@ SUBSYSTEM_DEF(machines)
return ..() return ..()
/datum/controller/subsystem/machines/proc/makepowernets() /datum/controller/subsystem/machines/proc/makepowernets()
for(var/datum/powernet/PN in powernets) for(var/datum/powernet/power_network as anything in powernets)
qdel(PN) qdel(power_network)
powernets.Cut() powernets.Cut()
for(var/obj/structure/cable/PC in GLOB.cable_list) for(var/obj/structure/cable/power_cable as anything in GLOB.cable_list)
if(!PC.powernet) if(!power_cable.powernet)
var/datum/powernet/NewPN = new() var/datum/powernet/new_powernet = new()
NewPN.add_cable(PC) new_powernet.add_cable(power_cable)
propagate_network(PC,PC.powernet) propagate_network(power_cable, power_cable.powernet)
/datum/controller/subsystem/machines/stat_entry(msg) /datum/controller/subsystem/machines/stat_entry(msg)
msg = "M:[length(processing)]|PN:[length(powernets)]" msg = "M:[length(processing)]|PN:[length(powernets)]"
return ..() return ..()
/datum/controller/subsystem/machines/fire(resumed = FALSE) /datum/controller/subsystem/machines/fire(resumed = FALSE)
if (!resumed) if (!resumed)
for(var/datum/powernet/Powernet in powernets) for(var/datum/powernet/powernet as anything in powernets)
Powernet.reset() //reset the power state. powernet.reset() //reset the power state.
src.currentrun = processing.Copy() src.currentrun = processing.Copy()
//cache for sanic speed (lists are references anyways) //cache for sanic speed (lists are references anyways)
@@ -40,13 +39,9 @@ SUBSYSTEM_DEF(machines)
while(currentrun.len) while(currentrun.len)
var/obj/machinery/thing = currentrun[currentrun.len] var/obj/machinery/thing = currentrun[currentrun.len]
currentrun.len-- currentrun.len--
if(!QDELETED(thing) && thing.process(wait * 0.1) != PROCESS_KILL) if(QDELETED(thing) || thing.process(wait * 0.1) == PROCESS_KILL)
if(thing.use_power)
thing.auto_use_power() //add back the power state
else
processing -= thing processing -= thing
if (!QDELETED(thing)) thing.datum_flags &= ~DF_ISPROCESSING
thing.datum_flags &= ~DF_ISPROCESSING
if (MC_TICK_CHECK) if (MC_TICK_CHECK)
return return

View File

@@ -92,6 +92,9 @@
///Used to decide what the maximum time between ambience is ///Used to decide what the maximum time between ambience is
var/max_ambience_cooldown = 60 SECONDS //SKYRAT EDIT CHANGE - ORIGINAL: 90 var/max_ambience_cooldown = 60 SECONDS //SKYRAT EDIT CHANGE - ORIGINAL: 90
var/list/air_vent_info = list()
var/list/air_scrub_info = list()
/** /**
* A list of teleport locations * A list of teleport locations
* *
@@ -432,8 +435,6 @@ GLOBAL_LIST_EMPTY(teleportlocs)
* Updates the area icon, calls power change on all machinees in the area, and sends the `COMSIG_AREA_POWER_CHANGE` signal. * Updates the area icon, calls power change on all machinees in the area, and sends the `COMSIG_AREA_POWER_CHANGE` signal.
*/ */
/area/proc/power_change() /area/proc/power_change()
for(var/obj/machinery/M in src) // for each machine in the area
M.power_change() // reverify power status (to update icons etc.)
SEND_SIGNAL(src, COMSIG_AREA_POWER_CHANGE) SEND_SIGNAL(src, COMSIG_AREA_POWER_CHANGE)
update_appearance() update_appearance()
@@ -452,13 +453,28 @@ GLOBAL_LIST_EMPTY(teleportlocs)
power_usage[powerchannel] += value power_usage[powerchannel] += value
/** /**
* Clear all power usage in area * Remove a static amount of power load to an area
* *
* Clears all power used for equipment, light and environment channels * Possible channels
* *AREA_USAGE_STATIC_EQUIP
* *AREA_USAGE_STATIC_LIGHT
* *AREA_USAGE_STATIC_ENVIRON
*/
/area/proc/removeStaticPower(value, powerchannel)
switch(powerchannel)
if(AREA_USAGE_STATIC_START to AREA_USAGE_STATIC_END)
power_usage[powerchannel] -= value
/**
* Clear all non-static power usage in area
*
* Clears all power used for the dynamic equipment, light and environment channels
*/ */
/area/proc/clear_usage() /area/proc/clear_usage()
for(var/i in AREA_USAGE_DYNAMIC_START to AREA_USAGE_DYNAMIC_END) power_usage[AREA_USAGE_EQUIP] = 0
power_usage[i] = 0 power_usage[AREA_USAGE_LIGHT] = 0
power_usage[AREA_USAGE_ENVIRON] = 0
/** /**
* Add a power value amount to the stored used_x variables * Add a power value amount to the stored used_x variables

View File

@@ -5,7 +5,7 @@
name = "bluespace gigabeacon" name = "bluespace gigabeacon"
desc = "A device that draws power from bluespace and creates a permanent tracking beacon." desc = "A device that draws power from bluespace and creates a permanent tracking beacon."
layer = LOW_OBJ_LAYER layer = LOW_OBJ_LAYER
use_power = IDLE_POWER_USE use_power = NO_POWER_USE
idle_power_usage = 0 idle_power_usage = 0
var/obj/item/beacon/Beacon var/obj/item/beacon/Beacon

View File

@@ -39,18 +39,22 @@
* EMPED -- temporary broken by EMP pulse * EMPED -- temporary broken by EMP pulse
* *
*Class Procs: *Class Procs:
* Initialize() 'game/machinery/machine.dm' * Initialize()
* *
* Destroy() 'game/machinery/machine.dm' * Destroy()
* *
* auto_use_power() 'game/machinery/machine.dm' * update_mode_power_usage()
* This proc determines how power mode power is deducted by the machine. * updates the static_power_usage var of this machine and makes its static power usage from its area accurate.
* 'auto_use_power()' is called by the 'master_controller' game_controller every * called after the idle or active power usage has been changed.
* tick. *
* update_power_channel()
* updates the static_power_usage var of this machine and makes its static power usage from its area accurate.
* called after the power_channel var has been changed or called to change the var itself.
*
* unset_static_power()
* completely removes the current static power usage of this machine from its area.
* used in the other power updating procs to then readd the correct power usage.
* *
* Return Value:
* return:1 -- if object is powered
* return:0 -- if object is not powered.
* *
* Default definition uses 'use_power', 'power_channel', 'active_power_usage', * Default definition uses 'use_power', 'power_channel', 'active_power_usage',
* 'idle_power_usage', 'powered()', and 'use_power()' implement behavior. * 'idle_power_usage', 'powered()', and 'use_power()' implement behavior.
@@ -99,11 +103,15 @@
var/machine_stat = NONE var/machine_stat = NONE
var/use_power = IDLE_POWER_USE var/use_power = IDLE_POWER_USE
//0 = dont run the auto //0 = dont use power
//1 = run auto, use idle //1 = use idle_power_usage
//2 = run auto, use active //2 = use active_power_usage
///the amount of static power load this machine adds to its area's power_usage list when use_power = IDLE_POWER_USE
var/idle_power_usage = 0 var/idle_power_usage = 0
///the amount of static power load this machine adds to its area's power_usage list when use_power = ACTIVE_POWER_USE
var/active_power_usage = 0 var/active_power_usage = 0
///the current amount of static power usage this machine is taking from its area
var/static_power_usage = 0
var/power_channel = AREA_USAGE_EQUIP var/power_channel = AREA_USAGE_EQUIP
//AREA_USAGE_EQUIP,AREA_USAGE_ENVIRON or AREA_USAGE_LIGHT //AREA_USAGE_EQUIP,AREA_USAGE_ENVIRON or AREA_USAGE_LIGHT
///A combination of factors such as having power, not being broken and so on. Boolean. ///A combination of factors such as having power, not being broken and so on. Boolean.
@@ -154,6 +162,63 @@
return INITIALIZE_HINT_LATELOAD return INITIALIZE_HINT_LATELOAD
/obj/machinery/LateInitialize()
. = ..()
power_change()
if(use_power == NO_POWER_USE)
return
update_current_power_usage()
setup_area_power_relationship()
/obj/machinery/Destroy()
GLOB.machines.Remove(src)
end_processing()
dump_inventory_contents()
QDEL_LIST(component_parts)
QDEL_NULL(circuit)
unset_static_power()
return ..()
/**
* proc to call when the machine starts to require power after a duration of not requiring power
* sets up power related connections to its area if it exists and becomes area sensitive
* does not affect power usage itself
*/
/obj/machinery/proc/setup_area_power_relationship()
become_area_sensitive(INNATE_TRAIT)
var/area/our_area = get_area(src)
if(our_area)
RegisterSignal(our_area, COMSIG_AREA_POWER_CHANGE, .proc/power_change)
RegisterSignal(src, COMSIG_ENTER_AREA, .proc/on_enter_area)
RegisterSignal(src, COMSIG_EXIT_AREA, .proc/on_exit_area)
/**
* proc to call when the machine stops requiring power after a duration of requiring power
* saves memory by removing the power relationship with its area if it exists and loses area sensitivity
* does not affect power usage itself
*/
/obj/machinery/proc/remove_area_power_relationship()
var/area/our_area = get_area(src)
if(our_area)
UnregisterSignal(our_area, COMSIG_AREA_POWER_CHANGE)
REMOVE_TRAIT(src, TRAIT_AREA_SENSITIVE, INNATE_TRAIT)
UnregisterSignal(src, COMSIG_ENTER_AREA)
UnregisterSignal(src, COMSIG_EXIT_AREA)
/obj/machinery/proc/on_enter_area(datum/source, area/area_to_register)
SIGNAL_HANDLER
update_current_power_usage()
power_change()
RegisterSignal(area_to_register, COMSIG_AREA_POWER_CHANGE, .proc/power_change)
/obj/machinery/proc/on_exit_area(datum/source, area/area_to_unregister)
SIGNAL_HANDLER
unset_static_power()
UnregisterSignal(area_to_unregister, COMSIG_AREA_POWER_CHANGE)
/obj/machinery/proc/set_occupant(atom/movable/new_occupant) /obj/machinery/proc/set_occupant(atom/movable/new_occupant)
SHOULD_CALL_PARENT(TRUE) SHOULD_CALL_PARENT(TRUE)
@@ -170,20 +235,6 @@
var/datum/controller/subsystem/processing/subsystem = locate(subsystem_type) in Master.subsystems var/datum/controller/subsystem/processing/subsystem = locate(subsystem_type) in Master.subsystems
STOP_PROCESSING(subsystem, src) STOP_PROCESSING(subsystem, src)
/obj/machinery/LateInitialize()
. = ..()
power_change()
become_area_sensitive(ROUNDSTART_TRAIT)
RegisterSignal(src, COMSIG_ENTER_AREA, .proc/power_change)
/obj/machinery/Destroy()
GLOB.machines.Remove(src)
end_processing()
dump_inventory_contents()
QDEL_LIST(component_parts)
QDEL_NULL(circuit)
return ..()
/obj/machinery/proc/locate_machinery() /obj/machinery/proc/locate_machinery()
return return
@@ -315,15 +366,119 @@
updateUsrDialog() updateUsrDialog()
update_appearance() update_appearance()
/obj/machinery/proc/auto_use_power() ///updates the use_power var for this machine and updates its static power usage from its area to reflect the new value
if(!powered(power_channel)) /obj/machinery/proc/update_use_power(new_use_power)
SHOULD_CALL_PARENT(TRUE)
if(new_use_power == use_power)
return FALSE return FALSE
if(use_power == IDLE_POWER_USE)
use_power(idle_power_usage,power_channel) unset_static_power()
else if(use_power >= ACTIVE_POWER_USE)
use_power(active_power_usage,power_channel) var/new_usage = 0
switch(new_use_power)
if(IDLE_POWER_USE)
new_usage = idle_power_usage
if(ACTIVE_POWER_USE)
new_usage = active_power_usage
if(use_power == NO_POWER_USE)
setup_area_power_relationship()
else if(new_use_power == NO_POWER_USE)
remove_area_power_relationship()
static_power_usage = new_usage
if(new_usage)
var/area/our_area = get_area(src)
our_area?.addStaticPower(new_usage, DYNAMIC_TO_STATIC_CHANNEL(power_channel))
use_power = new_use_power
return TRUE return TRUE
///updates the power channel this machine uses. removes the static power usage from the old channel and readds it to the new channel
/obj/machinery/proc/update_power_channel(new_power_channel)
SHOULD_CALL_PARENT(TRUE)
if(new_power_channel == power_channel)
return FALSE
var/usage = unset_static_power()
var/area/our_area = get_area(src)
if(our_area && usage)
our_area.addStaticPower(usage, DYNAMIC_TO_STATIC_CHANNEL(new_power_channel))
power_channel = new_power_channel
return TRUE
///internal proc that removes all static power usage from the current area
/obj/machinery/proc/unset_static_power()
SHOULD_NOT_OVERRIDE(TRUE)
var/old_usage = static_power_usage
var/area/our_area = get_area(src)
if(our_area && old_usage)
our_area.removeStaticPower(old_usage, DYNAMIC_TO_STATIC_CHANNEL(power_channel))
static_power_usage = 0
return old_usage
/**
* sets the power_usage linked to the specified use_power_mode to new_usage
* e.g. update_mode_power_usage(ACTIVE_POWER_USE, 10) sets active_power_use = 10 and updates its power draw from the machines area if use_power == ACTIVE_POWER_USE
*
* Arguments:
* * use_power_mode - the use_power power mode to change. if IDLE_POWER_USE changes idle_power_usage, ACTIVE_POWER_USE changes active_power_usage
* * new_usage - the new value to set the specified power mode var to
*/
/obj/machinery/proc/update_mode_power_usage(use_power_mode, new_usage)
SHOULD_CALL_PARENT(TRUE)
if(use_power_mode == NO_POWER_USE)
stack_trace("trying to set the power usage associated with NO_POWER_USE in update_mode_power_usage()!")
return FALSE
unset_static_power() //completely remove our static_power_usage from our area, then readd new_usage
switch(use_power_mode)
if(IDLE_POWER_USE)
idle_power_usage = new_usage
if(ACTIVE_POWER_USE)
active_power_usage = new_usage
if(use_power_mode == use_power)
static_power_usage = new_usage
var/area/our_area = get_area(src)
if(our_area)
our_area.addStaticPower(static_power_usage, DYNAMIC_TO_STATIC_CHANNEL(power_channel))
return TRUE
///makes this machine draw power from its area according to which use_power mode it is set to
/obj/machinery/proc/update_current_power_usage()
if(static_power_usage)
unset_static_power()
var/area/our_area = get_area(src)
if(!our_area)
return FALSE
switch(use_power)
if(IDLE_POWER_USE)
static_power_usage = idle_power_usage
if(ACTIVE_POWER_USE)
static_power_usage = active_power_usage
if(NO_POWER_USE)
return
if(static_power_usage)
our_area.addStaticPower(static_power_usage, DYNAMIC_TO_STATIC_CHANNEL(power_channel))
return TRUE
///Called when we want to change the value of the `is_operational` variable. Boolean. ///Called when we want to change the value of the `is_operational` variable. Boolean.
/obj/machinery/proc/set_is_operational(new_value) /obj/machinery/proc/set_is_operational(new_value)

View File

@@ -67,23 +67,20 @@
..() ..()
/obj/machinery/dish_drive/RefreshParts() /obj/machinery/dish_drive/RefreshParts()
idle_power_usage = initial(idle_power_usage)
active_power_usage = initial(active_power_usage)
use_power = initial(use_power)
var/total_rating = 0 var/total_rating = 0
for(var/obj/item/stock_parts/S in component_parts) for(var/obj/item/stock_parts/S in component_parts)
total_rating += S.rating total_rating += S.rating
if(total_rating >= 9) if(total_rating >= 9)
active_power_usage = 0 update_mode_power_usage(ACTIVE_POWER_USE, 0)
use_power = NO_POWER_USE
else else
idle_power_usage = max(0, idle_power_usage - total_rating) update_mode_power_usage(IDLE_POWER_USE, max(0, initial(idle_power_usage) - total_rating))
active_power_usage = max(0, active_power_usage - total_rating) update_mode_power_usage(ACTIVE_POWER_USE, max(0, initial(active_power_usage) - total_rating))
var/obj/item/circuitboard/machine/dish_drive/board = locate() in component_parts var/obj/item/circuitboard/machine/dish_drive/board = locate() in component_parts
if(board) if(board)
suction_enabled = board.suction suction_enabled = board.suction
transmit_enabled = board.transmit transmit_enabled = board.transmit
/obj/machinery/dish_drive/process() /obj/machinery/dish_drive/process()
if(time_since_dishes <= world.time && transmit_enabled) if(time_since_dishes <= world.time && transmit_enabled)
do_the_dishes() do_the_dishes()

View File

@@ -434,12 +434,7 @@ Possible to do for anyone motivated enough:
/obj/machinery/holopad/process() /obj/machinery/holopad/process()
if(LAZYLEN(masters)) if(LAZYLEN(masters))
for(var/I in masters) for(var/mob/living/master as anything in masters)
var/mob/living/master = I
var/mob/living/silicon/ai/AI = master
if(!istype(AI))
AI = null
if(!is_operational || !validate_user(master)) if(!is_operational || !validate_user(master))
clear_holo(master) clear_holo(master)
@@ -448,22 +443,23 @@ Possible to do for anyone motivated enough:
ringing = FALSE ringing = FALSE
for(var/I in holo_calls) for(var/datum/holocall/holocall as anything in holo_calls)
var/datum/holocall/HC = I if(holocall.connected_holopad == src)
if(HC.connected_holopad != src) continue
if(force_answer_call && world.time > (HC.call_start_time + (HOLOPAD_MAX_DIAL_TIME / 2)))
HC.Answer(src)
break
if(HC.head_call && !secure)
HC.Answer(src)
break
if(outgoing_call)
HC.Disconnect(src)//can't answer calls while calling
else
playsound(src, 'sound/machines/twobeep.ogg', 100) //bring, bring!
ringing = TRUE
update_appearance() if(force_answer_call && world.time > (holocall.call_start_time + (HOLOPAD_MAX_DIAL_TIME / 2)))
holocall.Answer(src)
break
if(holocall.head_call && !secure)
holocall.Answer(src)
break
if(outgoing_call)
holocall.Disconnect(src)//can't answer calls while calling
else
playsound(src, 'sound/machines/twobeep.ogg', 100) //bring, bring!
ringing = TRUE
update_appearance(UPDATE_ICON_STATE)
/obj/machinery/holopad/proc/activate_holo(mob/living/user) /obj/machinery/holopad/proc/activate_holo(mob/living/user)
var/mob/living/silicon/ai/AI = user var/mob/living/silicon/ai/AI = user
@@ -527,8 +523,8 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
/obj/machinery/holopad/proc/SetLightsAndPower() /obj/machinery/holopad/proc/SetLightsAndPower()
var/total_users = LAZYLEN(masters) + LAZYLEN(holo_calls) var/total_users = LAZYLEN(masters) + LAZYLEN(holo_calls)
use_power = total_users > 0 ? ACTIVE_POWER_USE : IDLE_POWER_USE update_use_power(total_users > 0 ? ACTIVE_POWER_USE : IDLE_POWER_USE)
active_power_usage = HOLOPAD_PASSIVE_POWER_USAGE + (HOLOGRAM_POWER_USAGE * total_users) update_mode_power_usage(ACTIVE_POWER_USE, HOLOPAD_PASSIVE_POWER_USAGE + (HOLOGRAM_POWER_USAGE * total_users))
if(total_users || replay_mode) if(total_users || replay_mode)
set_light(2) set_light(2)
else else

View File

@@ -3,7 +3,7 @@
desc = "A bluespace pad able to thrust matter through bluespace, teleporting it to or from nearby locations." desc = "A bluespace pad able to thrust matter through bluespace, teleporting it to or from nearby locations."
icon = 'icons/obj/telescience.dmi' icon = 'icons/obj/telescience.dmi'
icon_state = "lpad-idle" icon_state = "lpad-idle"
use_power = TRUE use_power = IDLE_POWER_USE
idle_power_usage = 200 idle_power_usage = 200
active_power_usage = 2500 active_power_usage = 2500
hud_possible = list(DIAG_LAUNCHPAD_HUD) hud_possible = list(DIAG_LAUNCHPAD_HUD)
@@ -212,7 +212,7 @@
icon_state = "blpad-idle" icon_state = "blpad-idle"
icon_teleport = "blpad-beam" icon_teleport = "blpad-beam"
anchored = FALSE anchored = FALSE
use_power = FALSE use_power = IDLE_POWER_USE
idle_power_usage = 0 idle_power_usage = 0
active_power_usage = 0 active_power_usage = 0
teleport_speed = 20 teleport_speed = 20

View File

@@ -47,12 +47,12 @@
charging = new_charging charging = new_charging
if (new_charging) if (new_charging)
START_PROCESSING(SSmachines, src) START_PROCESSING(SSmachines, src)
update_use_power(ACTIVE_POWER_USE)
finished_recharging = FALSE finished_recharging = FALSE
use_power = ACTIVE_POWER_USE
using_power = TRUE using_power = TRUE
update_appearance() update_appearance()
else else
use_power = IDLE_POWER_USE update_use_power(IDLE_POWER_USE)
using_power = FALSE using_power = FALSE
update_appearance() update_appearance()

View File

@@ -90,12 +90,12 @@
/obj/machinery/recharge_station/open_machine() /obj/machinery/recharge_station/open_machine()
. = ..() . = ..()
use_power = IDLE_POWER_USE update_use_power(IDLE_POWER_USE)
/obj/machinery/recharge_station/close_machine() /obj/machinery/recharge_station/close_machine()
. = ..() . = ..()
if(occupant) if(occupant)
use_power = ACTIVE_POWER_USE //It always tries to charge, even if it can't. update_use_power(ACTIVE_POWER_USE) //It always tries to charge, even if it can't.
add_fingerprint(occupant) add_fingerprint(occupant)
/obj/machinery/recharge_station/update_icon_state() /obj/machinery/recharge_station/update_icon_state()

View File

@@ -108,13 +108,13 @@
target.apply_status_effect(STATUS_EFFECT_STASIS, STASIS_MACHINE_EFFECT) target.apply_status_effect(STATUS_EFFECT_STASIS, STASIS_MACHINE_EFFECT)
ADD_TRAIT(target, TRAIT_TUMOR_SUPPRESSED, TRAIT_GENERIC) ADD_TRAIT(target, TRAIT_TUMOR_SUPPRESSED, TRAIT_GENERIC)
target.extinguish_mob() target.extinguish_mob()
use_power = ACTIVE_POWER_USE update_use_power(ACTIVE_POWER_USE)
/obj/machinery/stasis/proc/thaw_them(mob/living/target) /obj/machinery/stasis/proc/thaw_them(mob/living/target)
target.remove_status_effect(STATUS_EFFECT_STASIS, STASIS_MACHINE_EFFECT) target.remove_status_effect(STATUS_EFFECT_STASIS, STASIS_MACHINE_EFFECT)
REMOVE_TRAIT(target, TRAIT_TUMOR_SUPPRESSED, TRAIT_GENERIC) REMOVE_TRAIT(target, TRAIT_TUMOR_SUPPRESSED, TRAIT_GENERIC)
if(target == occupant) if(target == occupant)
use_power = IDLE_POWER_USE update_use_power(IDLE_POWER_USE)
/obj/machinery/stasis/post_buckle_mob(mob/living/L) /obj/machinery/stasis/post_buckle_mob(mob/living/L)
if(!can_be_occupant(L)) if(!can_be_occupant(L))
@@ -131,8 +131,8 @@
update_appearance() update_appearance()
/obj/machinery/stasis/process() /obj/machinery/stasis/process()
if( !( occupant && isliving(occupant) && check_nap_violations() ) ) if(!(occupant && isliving(occupant) && check_nap_violations()))
use_power = IDLE_POWER_USE update_use_power(IDLE_POWER_USE)
return return
var/mob/living/L_occupant = occupant var/mob/living/L_occupant = occupant
if(stasis_running()) if(stasis_running())

View File

@@ -63,10 +63,7 @@
return ..() return ..()
/obj/machinery/ntnet_relay/process(delta_time) /obj/machinery/ntnet_relay/process(delta_time)
if(is_operational) update_use_power(is_operational ? ACTIVE_POWER_USE : IDLE_POWER_USE)
use_power = ACTIVE_POWER_USE
else
use_power = IDLE_POWER_USE
update_appearance() update_appearance()

View File

@@ -1,37 +1,43 @@
// A datum for dealing with threshold limit values
/datum/tlv /datum/tlv
var/min2 var/warning_min
var/min1 var/warning_max
var/max1 var/hazard_min
var/max2 var/hazard_max
/datum/tlv/New(min2 as num, min1 as num, max1 as num, max2 as num) /datum/tlv/New(min2 as num, min1 as num, max1 as num, max2 as num)
if(min2) src.min2 = min2 if(min2)
if(min1) src.min1 = min1 hazard_min = min2
if(max1) src.max1 = max1 if(min1)
if(max2) src.max2 = max2 warning_min = min1
if(max1)
warning_max = max1
if(max2)
hazard_max = max2
/datum/tlv/proc/get_danger_level(val as num) /datum/tlv/proc/get_danger_level(val)
if(max2 != -1 && val >= max2) if(hazard_max != TLV_DONT_CHECK && val >= hazard_max)
return 2 return TLV_OUTSIDE_HAZARD_LIMIT
if(min2 != -1 && val <= min2) if(hazard_min != TLV_DONT_CHECK && val <= hazard_min)
return 2 return TLV_OUTSIDE_HAZARD_LIMIT
if(max1 != -1 && val >= max1) if(warning_max != TLV_DONT_CHECK && val >= warning_max)
return 1 return TLV_OUTSIDE_WARNING_LIMIT
if(min1 != -1 && val <= min1) if(warning_min != TLV_DONT_CHECK && val <= warning_min)
return 1 return TLV_OUTSIDE_WARNING_LIMIT
return 0
return TLV_NO_DANGER
/datum/tlv/no_checks /datum/tlv/no_checks
min2 = -1 hazard_min = TLV_DONT_CHECK
min1 = -1 warning_min = TLV_DONT_CHECK
max1 = -1 warning_max = TLV_DONT_CHECK
max2 = -1 hazard_max = TLV_DONT_CHECK
/datum/tlv/dangerous /datum/tlv/dangerous
min2 = -1 hazard_min = TLV_DONT_CHECK
min1 = -1 warning_min = TLV_DONT_CHECK
max1 = 0.2 warning_max = 0.2
max2 = 0.5 hazard_max = 0.5
/obj/item/electronics/airalarm /obj/item/electronics/airalarm
name = "air alarm electronics" name = "air alarm electronics"
@@ -85,8 +91,10 @@
///Represents a signel source of atmos alarms, complains to all the listeners if one of our thresholds is violated ///Represents a signel source of atmos alarms, complains to all the listeners if one of our thresholds is violated
var/datum/alarm_handler/alarm_manager var/datum/alarm_handler/alarm_manager
var/static/list/atmos_connections = list(COMSIG_TURF_EXPOSE = .proc/check_air_dangerlevel)
var/list/TLV = list( // Breathable air. var/list/TLV = list( // Breathable air.
"pressure" = new/datum/tlv(HAZARD_LOW_PRESSURE, WARNING_LOW_PRESSURE, WARNING_HIGH_PRESSURE, HAZARD_HIGH_PRESSURE), // kPa. Values are min2, min1, max1, max2 "pressure" = new/datum/tlv(HAZARD_LOW_PRESSURE, WARNING_LOW_PRESSURE, WARNING_HIGH_PRESSURE, HAZARD_HIGH_PRESSURE), // kPa. Values are hazard_min, warning_min, warning_max, hazard_max
"temperature" = new/datum/tlv(BODYTEMP_COLD_WARNING_1, BODYTEMP_COLD_WARNING_1+10, BODYTEMP_HEAT_WARNING_1-27, BODYTEMP_HEAT_WARNING_1), "temperature" = new/datum/tlv(BODYTEMP_COLD_WARNING_1, BODYTEMP_COLD_WARNING_1+10, BODYTEMP_HEAT_WARNING_1-27, BODYTEMP_HEAT_WARNING_1),
/datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa /datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
/datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000), /datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000),
@@ -111,109 +119,6 @@
/datum/gas/halon = new/datum/tlv/dangerous /datum/gas/halon = new/datum/tlv/dangerous
) )
/obj/machinery/airalarm/server // No checks here.
TLV = list(
"pressure" = new/datum/tlv/no_checks,
"temperature" = new/datum/tlv/no_checks,
/datum/gas/oxygen = new/datum/tlv/no_checks,
/datum/gas/nitrogen = new/datum/tlv/no_checks,
/datum/gas/carbon_dioxide = new/datum/tlv/no_checks,
/datum/gas/miasma = new/datum/tlv/no_checks,
/datum/gas/plasma = new/datum/tlv/no_checks,
/datum/gas/nitrous_oxide = new/datum/tlv/no_checks,
/datum/gas/bz = new/datum/tlv/no_checks,
/datum/gas/hypernoblium = new/datum/tlv/no_checks,
/datum/gas/water_vapor = new/datum/tlv/no_checks,
/datum/gas/tritium = new/datum/tlv/no_checks,
/datum/gas/stimulum = new/datum/tlv/no_checks,
/datum/gas/nitryl = new/datum/tlv/no_checks,
/datum/gas/pluoxium = new/datum/tlv/no_checks,
/datum/gas/freon = new/datum/tlv/no_checks,
/datum/gas/hydrogen = new/datum/tlv/no_checks,
/datum/gas/healium = new/datum/tlv/dangerous,
/datum/gas/proto_nitrate = new/datum/tlv/dangerous,
/datum/gas/zauker = new/datum/tlv/dangerous,
/datum/gas/helium = new/datum/tlv/dangerous,
/datum/gas/antinoblium = new/datum/tlv/dangerous,
/datum/gas/halon = new/datum/tlv/dangerous
)
/obj/machinery/airalarm/kitchen_cold_room // Kitchen cold rooms start off at -14°C or 259.15K.
TLV = list(
"pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE * 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa
"temperature" = new/datum/tlv(COLD_ROOM_TEMP-40, COLD_ROOM_TEMP-20, COLD_ROOM_TEMP+20, COLD_ROOM_TEMP+40),
/datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
/datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000),
/datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10),
/datum/gas/miasma = new/datum/tlv/(-1, -1, 2, 5),
/datum/gas/plasma = new/datum/tlv/dangerous,
/datum/gas/nitrous_oxide = new/datum/tlv/dangerous,
/datum/gas/bz = new/datum/tlv/dangerous,
/datum/gas/hypernoblium = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic
/datum/gas/water_vapor = new/datum/tlv/dangerous,
/datum/gas/tritium = new/datum/tlv/dangerous,
/datum/gas/stimulum = new/datum/tlv/dangerous,
/datum/gas/nitryl = new/datum/tlv/dangerous,
/datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
/datum/gas/freon = new/datum/tlv/dangerous,
/datum/gas/hydrogen = new/datum/tlv/dangerous,
/datum/gas/healium = new/datum/tlv/dangerous,
/datum/gas/proto_nitrate = new/datum/tlv/dangerous,
/datum/gas/zauker = new/datum/tlv/dangerous,
/datum/gas/helium = new/datum/tlv/dangerous,
/datum/gas/antinoblium = new/datum/tlv/dangerous,
/datum/gas/halon = new/datum/tlv/dangerous
)
/obj/machinery/airalarm/unlocked
locked = FALSE
/obj/machinery/airalarm/engine
name = "engine air alarm"
locked = FALSE
req_access = null
req_one_access = list(ACCESS_ATMOSPHERICS, ACCESS_ENGINE)
/obj/machinery/airalarm/mixingchamber
name = "chamber air alarm"
locked = FALSE
req_access = null
req_one_access = list(ACCESS_ATMOSPHERICS, ACCESS_ORDNANCE)
/obj/machinery/airalarm/all_access
name = "all-access air alarm"
desc = "This particular atmos control unit appears to have no access restrictions."
locked = FALSE
req_access = null
req_one_access = null
/obj/machinery/airalarm/syndicate //general syndicate access
req_access = list(ACCESS_SYNDICATE)
/obj/machinery/airalarm/away //general away mission access
req_access = list(ACCESS_AWAY_GENERAL)
/obj/machinery/airalarm/directional/north //Pixel offsets get overwritten on New()
dir = SOUTH
pixel_y = 24
/obj/machinery/airalarm/directional/south
dir = NORTH
pixel_y = -24
/obj/machinery/airalarm/directional/east
dir = WEST
pixel_x = 24
/obj/machinery/airalarm/directional/west
dir = EAST
pixel_x = -24
//all air alarms in area are connected via magic
/area
var/list/air_vent_info = list()
var/list/air_scrub_info = list()
/obj/machinery/airalarm/New(loc, ndir, nbuild) /obj/machinery/airalarm/New(loc, ndir, nbuild)
..() ..()
wires = new /datum/wires/airalarm(src) wires = new /datum/wires/airalarm(src)
@@ -241,6 +146,7 @@
/obj/machinery/airalarm/Initialize(mapload) /obj/machinery/airalarm/Initialize(mapload)
. = ..() . = ..()
set_frequency(frequency) set_frequency(frequency)
AddElement(/datum/element/connect_loc, atmos_connections)
AddComponent(/datum/component/usb_port, list( AddComponent(/datum/component/usb_port, list(
/obj/item/circuit_component/air_alarm, /obj/item/circuit_component/air_alarm,
)) ))
@@ -367,27 +273,27 @@
selected = TLV["pressure"] selected = TLV["pressure"]
thresholds += list(list("name" = "Pressure", "settings" = list())) thresholds += list(list("name" = "Pressure", "settings" = list()))
thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "min2", "selected" = selected.min2)) thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "hazard_min", "selected" = selected.hazard_min))
thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "min1", "selected" = selected.min1)) thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "warning_min", "selected" = selected.warning_min))
thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "max1", "selected" = selected.max1)) thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "warning_max", "selected" = selected.warning_max))
thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "max2", "selected" = selected.max2)) thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "hazard_max", "selected" = selected.hazard_max))
selected = TLV["temperature"] selected = TLV["temperature"]
thresholds += list(list("name" = "Temperature", "settings" = list())) thresholds += list(list("name" = "Temperature", "settings" = list()))
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "min2", "selected" = selected.min2)) thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "hazard_min", "selected" = selected.hazard_min))
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "min1", "selected" = selected.min1)) thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "warning_min", "selected" = selected.warning_min))
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max1", "selected" = selected.max1)) thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "warning_max", "selected" = selected.warning_max))
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max2", "selected" = selected.max2)) thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "hazard_max", "selected" = selected.hazard_max))
for(var/gas_id in GLOB.meta_gas_info) for(var/gas_id in GLOB.meta_gas_info)
if(!(gas_id in TLV)) // We're not interested in this gas, it seems. if(!(gas_id in TLV)) // We're not interested in this gas, it seems.
continue continue
selected = TLV[gas_id] selected = TLV[gas_id]
thresholds += list(list("name" = GLOB.meta_gas_info[gas_id][META_GAS_NAME], "settings" = list())) thresholds += list(list("name" = GLOB.meta_gas_info[gas_id][META_GAS_NAME], "settings" = list()))
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min2", "selected" = selected.min2)) thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "hazard_min", "selected" = selected.hazard_min))
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min1", "selected" = selected.min1)) thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "warning_min", "selected" = selected.warning_min))
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "max1", "selected" = selected.max1)) thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "warning_max", "selected" = selected.warning_max))
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "max2", "selected" = selected.max2)) thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "hazard_max", "selected" = selected.hazard_max))
data["thresholds"] = thresholds data["thresholds"] = thresholds
return data return data
@@ -441,6 +347,9 @@
else else
tlv.vars[name] = round(value, 0.01) tlv.vars[name] = round(value, 0.01)
investigate_log(" treshold value for [env]:[name] was set to [value] by [key_name(usr)]",INVESTIGATE_ATMOS) investigate_log(" treshold value for [env]:[name] was set to [value] by [key_name(usr)]",INVESTIGATE_ATMOS)
var/turf/our_turf = get_turf(src)
var/datum/gas_mixture/environment = our_turf.return_air()
check_air_dangerlevel(our_turf, environment, environment.temperature)
. = TRUE . = TRUE
if("mode") if("mode")
mode = text2num(params["mode"]) mode = text2num(params["mode"])
@@ -668,33 +577,36 @@
icon_state = "alarm1" icon_state = "alarm1"
return ..() return ..()
/obj/machinery/airalarm/process() /**
* main proc for throwing a shitfit if the air isnt right.
* goes into warning mode if gas parameters are beyond the tlv warning bounds, goes into hazard mode if gas parameters are beyond tlv hazard bounds
*
*/
/obj/machinery/airalarm/proc/check_air_dangerlevel(turf/location, datum/gas_mixture/environment, exposed_temperature)
SIGNAL_HANDLER
if((machine_stat & (NOPOWER|BROKEN)) || shorted) if((machine_stat & (NOPOWER|BROKEN)) || shorted)
return return
var/turf/location = get_turf(src) var/datum/tlv/current_tlv
if(!location) //cache for sanic speed (lists are references anyways)
return var/list/cached_tlv = TLV
var/datum/tlv/cur_tlv
var/datum/gas_mixture/environment = location.return_air()
var/list/env_gases = environment.gases var/list/env_gases = environment.gases
var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume var/partial_pressure = R_IDEAL_GAS_EQUATION * exposed_temperature / environment.volume
cur_tlv = TLV["pressure"] current_tlv = cached_tlv["pressure"]
var/environment_pressure = environment.return_pressure() var/environment_pressure = environment.return_pressure()
var/pressure_dangerlevel = cur_tlv.get_danger_level(environment_pressure) var/pressure_dangerlevel = current_tlv.get_danger_level(environment_pressure)
cur_tlv = TLV["temperature"] current_tlv = cached_tlv["temperature"]
var/temperature_dangerlevel = cur_tlv.get_danger_level(environment.temperature) var/temperature_dangerlevel = current_tlv.get_danger_level(exposed_temperature)
var/gas_dangerlevel = 0 var/gas_dangerlevel = 0
for(var/gas_id in env_gases) for(var/gas_id in env_gases)
if(!(gas_id in TLV)) // We're not interested in this gas, it seems. if(!(gas_id in cached_tlv)) // We're not interested in this gas, it seems.
continue continue
cur_tlv = TLV[gas_id] current_tlv = cached_tlv[gas_id]
gas_dangerlevel = max(gas_dangerlevel, cur_tlv.get_danger_level(env_gases[gas_id][MOLES] * partial_pressure)) gas_dangerlevel = max(gas_dangerlevel, current_tlv.get_danger_level(env_gases[gas_id][MOLES] * partial_pressure))
environment.garbage_collect() environment.garbage_collect()
@@ -702,10 +614,10 @@
danger_level = max(pressure_dangerlevel, temperature_dangerlevel, gas_dangerlevel) danger_level = max(pressure_dangerlevel, temperature_dangerlevel, gas_dangerlevel)
if(old_danger_level != danger_level) if(old_danger_level != danger_level)
apply_danger_level() INVOKE_ASYNC(src, .proc/apply_danger_level)
if(mode == AALARM_MODE_REPLACEMENT && environment_pressure < ONE_ATMOSPHERE * 0.05) if(mode == AALARM_MODE_REPLACEMENT && environment_pressure < ONE_ATMOSPHERE * 0.05)
mode = AALARM_MODE_SCRUBBING mode = AALARM_MODE_SCRUBBING
apply_mode(src) INVOKE_ASYNC(src, .proc/apply_mode, src)
/obj/machinery/airalarm/proc/post_alert(alert_level) /obj/machinery/airalarm/proc/post_alert(alert_level)
@@ -894,6 +806,104 @@
new /obj/item/stack/cable_coil(loc, 3) new /obj/item/stack/cable_coil(loc, 3)
qdel(src) qdel(src)
/obj/machinery/airalarm/server // No checks here.
TLV = list(
"pressure" = new/datum/tlv/no_checks,
"temperature" = new/datum/tlv/no_checks,
/datum/gas/oxygen = new/datum/tlv/no_checks,
/datum/gas/nitrogen = new/datum/tlv/no_checks,
/datum/gas/carbon_dioxide = new/datum/tlv/no_checks,
/datum/gas/miasma = new/datum/tlv/no_checks,
/datum/gas/plasma = new/datum/tlv/no_checks,
/datum/gas/nitrous_oxide = new/datum/tlv/no_checks,
/datum/gas/bz = new/datum/tlv/no_checks,
/datum/gas/hypernoblium = new/datum/tlv/no_checks,
/datum/gas/water_vapor = new/datum/tlv/no_checks,
/datum/gas/tritium = new/datum/tlv/no_checks,
/datum/gas/stimulum = new/datum/tlv/no_checks,
/datum/gas/nitryl = new/datum/tlv/no_checks,
/datum/gas/pluoxium = new/datum/tlv/no_checks,
/datum/gas/freon = new/datum/tlv/no_checks,
/datum/gas/hydrogen = new/datum/tlv/no_checks,
/datum/gas/healium = new/datum/tlv/dangerous,
/datum/gas/proto_nitrate = new/datum/tlv/dangerous,
/datum/gas/zauker = new/datum/tlv/dangerous,
/datum/gas/helium = new/datum/tlv/dangerous,
/datum/gas/antinoblium = new/datum/tlv/dangerous,
/datum/gas/halon = new/datum/tlv/dangerous,
)
/obj/machinery/airalarm/kitchen_cold_room // Kitchen cold rooms start off at -14°C or 259.15K.
TLV = list(
"pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE * 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa
"temperature" = new/datum/tlv(COLD_ROOM_TEMP-40, COLD_ROOM_TEMP-20, COLD_ROOM_TEMP+20, COLD_ROOM_TEMP+40),
/datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
/datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000),
/datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10),
/datum/gas/miasma = new/datum/tlv/(-1, -1, 2, 5),
/datum/gas/plasma = new/datum/tlv/dangerous,
/datum/gas/nitrous_oxide = new/datum/tlv/dangerous,
/datum/gas/bz = new/datum/tlv/dangerous,
/datum/gas/hypernoblium = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic
/datum/gas/water_vapor = new/datum/tlv/dangerous,
/datum/gas/tritium = new/datum/tlv/dangerous,
/datum/gas/stimulum = new/datum/tlv/dangerous,
/datum/gas/nitryl = new/datum/tlv/dangerous,
/datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
/datum/gas/freon = new/datum/tlv/dangerous,
/datum/gas/hydrogen = new/datum/tlv/dangerous,
/datum/gas/healium = new/datum/tlv/dangerous,
/datum/gas/proto_nitrate = new/datum/tlv/dangerous,
/datum/gas/zauker = new/datum/tlv/dangerous,
/datum/gas/helium = new/datum/tlv/dangerous,
/datum/gas/antinoblium = new/datum/tlv/dangerous,
/datum/gas/halon = new/datum/tlv/dangerous,
)
/obj/machinery/airalarm/unlocked
locked = FALSE
/obj/machinery/airalarm/engine
name = "engine air alarm"
locked = FALSE
req_access = null
req_one_access = list(ACCESS_ATMOSPHERICS, ACCESS_ENGINE)
/obj/machinery/airalarm/mixingchamber
name = "chamber air alarm"
locked = FALSE
req_access = null
req_one_access = list(ACCESS_ATMOSPHERICS, ACCESS_ORDNANCE)
/obj/machinery/airalarm/all_access
name = "all-access air alarm"
desc = "This particular atmos control unit appears to have no access restrictions."
locked = FALSE
req_access = null
req_one_access = null
/obj/machinery/airalarm/syndicate //general syndicate access
req_access = list(ACCESS_SYNDICATE)
/obj/machinery/airalarm/away //general away mission access
req_access = list(ACCESS_AWAY_GENERAL)
/obj/machinery/airalarm/directional/north //Pixel offsets get overwritten on New()
dir = SOUTH
pixel_y = 24
/obj/machinery/airalarm/directional/south
dir = NORTH
pixel_y = -24
/obj/machinery/airalarm/directional/east
dir = WEST
pixel_x = 24
/obj/machinery/airalarm/directional/west
dir = EAST
pixel_x = -24
/obj/item/circuit_component/air_alarm /obj/item/circuit_component/air_alarm
display_name = "Air Alarm" display_name = "Air Alarm"
desc = "Controls levels of gases and their temperature as well as all vents and scrubbers in the room." desc = "Controls levels of gases and their temperature as well as all vents and scrubbers in the room."
@@ -968,10 +978,10 @@
return return
var/datum/tlv/settings = connected_alarm.TLV[options_map[current_option]] var/datum/tlv/settings = connected_alarm.TLV[options_map[current_option]]
settings.min2 = min_2 settings.hazard_min = min_2
settings.min1 = min_1 settings.warning_min = min_1
settings.max1 = max_1 settings.warning_max = max_1
settings.max2 = max_2 settings.hazard_max = max_2
#undef AALARM_MODE_SCRUBBING #undef AALARM_MODE_SCRUBBING
#undef AALARM_MODE_VENTING #undef AALARM_MODE_VENTING

View File

@@ -439,7 +439,7 @@
switch(action) switch(action)
if("power") if("power")
on = !on on = !on
use_power = on ? ACTIVE_POWER_USE : IDLE_POWER_USE update_use_power(on ? ACTIVE_POWER_USE : IDLE_POWER_USE)
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS) investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS)
. = TRUE . = TRUE
if("cooling") if("cooling")

View File

@@ -310,7 +310,7 @@
switch(action) switch(action)
if("start_power") if("start_power")
connected_core.start_power = !connected_core.start_power connected_core.start_power = !connected_core.start_power
connected_core.use_power = connected_core.start_power ? ACTIVE_POWER_USE : IDLE_POWER_USE connected_core.update_use_power(connected_core.start_power ? ACTIVE_POWER_USE : IDLE_POWER_USE)
. = TRUE . = TRUE
if("start_cooling") if("start_cooling")
connected_core.start_cooling = !connected_core.start_cooling connected_core.start_cooling = !connected_core.start_cooling

View File

@@ -188,7 +188,8 @@
if(machine_stat & (NOPOWER|BROKEN)) if(machine_stat & (NOPOWER|BROKEN))
return FALSE return FALSE
if(use_power == ACTIVE_POWER_USE) if(use_power == ACTIVE_POWER_USE)
active_power_usage = ((power_level + 1) * MIN_POWER_USAGE) //Max around 350 KW update_mode_power_usage(ACTIVE_POWER_USE, (power_level + 1) * MIN_POWER_USAGE) //Max around 350 KW
return TRUE return TRUE
///Checks if the gases in the input are the ones needed by the recipe ///Checks if the gases in the input are the ones needed by the recipe

View File

@@ -19,7 +19,7 @@
var/filter_types = list(/datum/gas/carbon_dioxide) var/filter_types = list(/datum/gas/carbon_dioxide)
var/volume_rate = 200 var/volume_rate = 200
var/widenet = 0 //is this scrubber acting on the 3x3 area around it. var/widenet = FALSE //is this scrubber acting on the 3x3 area around it.
var/list/turf/adjacent_turfs = list() var/list/turf/adjacent_turfs = list()
var/frequency = FREQ_ATMOS_CONTROL var/frequency = FREQ_ATMOS_CONTROL
@@ -50,22 +50,6 @@
adjacent_turfs.Cut() adjacent_turfs.Cut()
return ..() return ..()
/obj/machinery/atmospherics/components/unary/vent_scrubber/auto_use_power()
if(!on || welded || !is_operational || !powered(power_channel))
return FALSE
var/amount = idle_power_usage
if(scrubbing & SCRUBBING)
amount += idle_power_usage * length(filter_types)
else //scrubbing == SIPHONING
amount = active_power_usage
if(widenet)
amount += amount * (adjacent_turfs.len * (adjacent_turfs.len / 2))
use_power(amount, power_channel)
return TRUE
/obj/machinery/atmospherics/components/unary/vent_scrubber/update_icon_nopipes() /obj/machinery/atmospherics/components/unary/vent_scrubber/update_icon_nopipes()
cut_overlays() cut_overlays()
if(showpipe) if(showpipe)
@@ -162,7 +146,7 @@
if(air_contents.return_pressure() >= 50 * ONE_ATMOSPHERE) if(air_contents.return_pressure() >= 50 * ONE_ATMOSPHERE)
return FALSE return FALSE
if(scrubbing & SCRUBBING) if(scrubbing == SCRUBBING)
if(length(env_gases & filter_types)) if(length(env_gases & filter_types))
var/transfer_moles = min(1, volume_rate / environment.volume) * environment.total_moles() var/transfer_moles = min(1, volume_rate / environment.volume) * environment.total_moles()
@@ -209,19 +193,21 @@
if(widenet) if(widenet)
check_turfs() check_turfs()
//we populate a list of turfs with nonatmos-blocked cardinal turfs AND ///we populate a list of turfs with nonatmos-blocked cardinal turfs AND
// diagonal turfs that can share atmos with *both* of the cardinal turfs /// diagonal turfs that can share atmos with *both* of the cardinal turfs
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/check_turfs() /obj/machinery/atmospherics/components/unary/vent_scrubber/proc/check_turfs()
adjacent_turfs.Cut() adjacent_turfs.Cut()
var/turf/T = get_turf(src) var/turf/T = get_turf(src)
if(istype(T)) adjacent_turfs = T.GetAtmosAdjacentTurfs(alldir = TRUE)
adjacent_turfs = T.GetAtmosAdjacentTurfs(alldir = 1)
/obj/machinery/atmospherics/components/unary/vent_scrubber/receive_signal(datum/signal/signal) /obj/machinery/atmospherics/components/unary/vent_scrubber/receive_signal(datum/signal/signal)
if(!is_operational || !signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command")) if(!is_operational || !signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command"))
return return
var/old_widenet = widenet
var/old_scrubbing = scrubbing
var/old_filter_length = length(filter_types)
var/atom/signal_sender = signal.data["user"] var/atom/signal_sender = signal.data["user"]
if("power" in signal.data) if("power" in signal.data)
@@ -234,7 +220,6 @@
if("toggle_widenet" in signal.data) if("toggle_widenet" in signal.data)
widenet = !widenet widenet = !widenet
var/old_scrubbing = scrubbing
if("scrubbing" in signal.data) if("scrubbing" in signal.data)
scrubbing = text2num(signal.data["scrubbing"]) scrubbing = text2num(signal.data["scrubbing"])
if("toggle_scrubbing" in signal.data) if("toggle_scrubbing" in signal.data)
@@ -260,7 +245,25 @@
broadcast_status() broadcast_status()
update_appearance() update_appearance()
return
if(length(filter_types) == old_filter_length && old_scrubbing == scrubbing && old_widenet == widenet)
return
idle_power_usage = initial(idle_power_usage)
active_power_usage = initial(idle_power_usage)
var/new_power_usage = 0
if(scrubbing == SCRUBBING)
new_power_usage = idle_power_usage + idle_power_usage * length(filter_types)
update_use_power(IDLE_POWER_USE)
else
new_power_usage = active_power_usage
update_use_power(ACTIVE_POWER_USE)
if(widenet)
new_power_usage += new_power_usage * (length(adjacent_turfs) * (length(adjacent_turfs) / 2))
update_mode_power_usage(scrubbing == SCRUBBING ? IDLE_POWER_USE : ACTIVE_POWER_USE, new_power_usage)
/obj/machinery/atmospherics/components/unary/vent_scrubber/power_change() /obj/machinery/atmospherics/components/unary/vent_scrubber/power_change()
. = ..() . = ..()

View File

@@ -87,15 +87,15 @@
var/P = G.return_pressure() var/P = G.return_pressure()
switch(power_draw) switch(power_draw)
if(GASMINER_POWER_NONE) if(GASMINER_POWER_NONE)
active_power_usage = 0 update_use_power(ACTIVE_POWER_USE, 0)
if(GASMINER_POWER_STATIC) if(GASMINER_POWER_STATIC)
active_power_usage = power_draw_static update_use_power(ACTIVE_POWER_USE, power_draw_static)
if(GASMINER_POWER_MOLES) if(GASMINER_POWER_MOLES)
active_power_usage = spawn_mol * power_draw_dynamic_mol_coeff update_use_power(ACTIVE_POWER_USE, spawn_mol * power_draw_dynamic_mol_coeff)
if(GASMINER_POWER_KPA) if(GASMINER_POWER_KPA)
active_power_usage = P * power_draw_dynamic_kpa_coeff update_use_power(ACTIVE_POWER_USE, P * power_draw_dynamic_kpa_coeff)
if(GASMINER_POWER_FULLSCALE) if(GASMINER_POWER_FULLSCALE)
active_power_usage = (spawn_mol * power_draw_dynamic_mol_coeff) + (P * power_draw_dynamic_kpa_coeff) update_use_power(ACTIVE_POWER_USE, (spawn_mol * power_draw_dynamic_mol_coeff) + (P * power_draw_dynamic_kpa_coeff))
/obj/machinery/atmospherics/miner/proc/do_use_power(amount) /obj/machinery/atmospherics/miner/proc/do_use_power(amount)
var/turf/T = get_turf(src) var/turf/T = get_turf(src)

View File

@@ -202,7 +202,7 @@
if((!anchored && !movable) || !is_operational) if((!anchored && !movable) || !is_operational)
on = FALSE on = FALSE
update_appearance() update_appearance()
use_power = on ? ACTIVE_POWER_USE : IDLE_POWER_USE update_use_power(on ? ACTIVE_POWER_USE : IDLE_POWER_USE)
if(!on) if(!on)
return ..() return ..()

View File

@@ -216,7 +216,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
target = null target = null
dest.deactivate(src) dest.deactivate(src)
QDEL_NULL(portal) QDEL_NULL(portal)
use_power = IDLE_POWER_USE update_use_power(IDLE_POWER_USE)
update_appearance() update_appearance()
portal_visuals.reset_visuals() portal_visuals.reset_visuals()
@@ -244,7 +244,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
target.activate(destination) target.activate(destination)
portal_visuals.setup_visuals(target) portal_visuals.setup_visuals(target)
generate_bumper() generate_bumper()
use_power = ACTIVE_POWER_USE update_use_power(ACTIVE_POWER_USE)
update_appearance() update_appearance()
/obj/machinery/gateway/proc/Transfer(atom/movable/AM) /obj/machinery/gateway/proc/Transfer(atom/movable/AM)

View File

@@ -206,9 +206,9 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions())
/obj/machinery/exoscanner/proc/scan_change() /obj/machinery/exoscanner/proc/scan_change()
SIGNAL_HANDLER SIGNAL_HANDLER
if(GLOB.exoscanner_controller.current_scan) if(GLOB.exoscanner_controller.current_scan)
use_power = ACTIVE_POWER_USE update_use_power(ACTIVE_POWER_USE)
else else
use_power = IDLE_POWER_USE update_use_power(IDLE_POWER_USE)
update_icon_state() update_icon_state()
/obj/machinery/exoscanner/Destroy() /obj/machinery/exoscanner/Destroy()

View File

@@ -339,10 +339,10 @@
/obj/machinery/smartfridge/drying_rack/proc/toggle_drying(forceoff) /obj/machinery/smartfridge/drying_rack/proc/toggle_drying(forceoff)
if(drying || forceoff) if(drying || forceoff)
drying = FALSE drying = FALSE
use_power = IDLE_POWER_USE update_use_power(IDLE_POWER_USE)
else else
drying = TRUE drying = TRUE
use_power = ACTIVE_POWER_USE update_use_power(ACTIVE_POWER_USE)
update_appearance() update_appearance()
/obj/machinery/smartfridge/drying_rack/proc/rack_dry(obj/item/target) /obj/machinery/smartfridge/drying_rack/proc/rack_dry(obj/item/target)

View File

@@ -203,7 +203,7 @@ and clear when youre done! if you dont i will use :newspaper2: on you
spawning_simulation = TRUE spawning_simulation = TRUE
active = (map_id != offline_program) active = (map_id != offline_program)
use_power = active + IDLE_POWER_USE update_use_power(active + IDLE_POWER_USE)
program = map_id program = map_id
//clear the items from the previous program //clear the items from the previous program
@@ -326,7 +326,7 @@ and clear when youre done! if you dont i will use :newspaper2: on you
derez(item) derez(item)
for(var/obj/effect/holodeck_effect/holo_effect as anything in effects) for(var/obj/effect/holodeck_effect/holo_effect as anything in effects)
holo_effect.tick() holo_effect.tick()
active_power_usage = 50 + spawned.len * 3 + effects.len * 5 update_mode_power_usage(ACTIVE_POWER_USE, 50 + spawned.len * 3 + effects.len * 5)
/obj/machinery/computer/holodeck/proc/toggle_power(toggleOn = FALSE) /obj/machinery/computer/holodeck/proc/toggle_power(toggleOn = FALSE)
if(active == toggleOn) if(active == toggleOn)

View File

@@ -7,7 +7,8 @@
pixel_z = 8 pixel_z = 8
obj_flags = CAN_BE_HIT | UNIQUE_RENAME obj_flags = CAN_BE_HIT | UNIQUE_RENAME
circuit = /obj/item/circuitboard/machine/hydroponics circuit = /obj/item/circuitboard/machine/hydroponics
idle_power_usage = 0 idle_power_usage = 5000
use_power = NO_POWER_USE
///The amount of water in the tray (max 100) ///The amount of water in the tray (max 100)
var/waterlevel = 100 var/waterlevel = 100
///The maximum amount of water in the tray ///The maximum amount of water in the tray
@@ -125,6 +126,11 @@
else else
return ..() return ..()
/obj/machinery/hydroponics/power_change()
. = ..()
if(machine_stat & NOPOWER && self_sustaining)
self_sustaining = FALSE
/obj/machinery/hydroponics/process(delta_time) /obj/machinery/hydroponics/process(delta_time)
var/needs_update = 0 // Checks if the icon needs updating so we don't redraw empty trays every time var/needs_update = 0 // Checks if the icon needs updating so we don't redraw empty trays every time
@@ -132,8 +138,8 @@
myseed.forceMove(src) myseed.forceMove(src)
if(!powered() && self_sustaining) if(!powered() && self_sustaining)
visible_message(span_warning("[name]'s auto-grow functionality shuts off!")) visible_message("<span class='warning'>[name]'s auto-grow functionality shuts off!</span>")
idle_power_usage = 0 update_use_power(NO_POWER_USE)
self_sustaining = FALSE self_sustaining = FALSE
update_appearance() update_appearance()
@@ -767,12 +773,14 @@
return return
if(!powered()) if(!powered())
to_chat(user, span_warning("[name] has no power.")) to_chat(user, span_warning("[name] has no power."))
update_use_power(NO_POWER_USE)
return return
if(!anchored) if(!anchored)
return return
self_sustaining = !self_sustaining self_sustaining = !self_sustaining
idle_power_usage = self_sustaining ? 5000 : 0 update_use_power(self_sustaining ? IDLE_POWER_USE : NO_POWER_USE)
to_chat(user, "<span class='notice'>You [self_sustaining ? "activate" : "deactivated"] [src]'s autogrow function[self_sustaining ? ", maintaining the tray's health while using high amounts of power" : ""].") to_chat(user, "<span class='notice'>You [self_sustaining ? "activate" : "deactivated"] [src]'s autogrow function[self_sustaining ? ", maintaining the tray's health while using high amounts of power" : ""].")
update_appearance() update_appearance()
/obj/machinery/hydroponics/AltClick(mob/user) /obj/machinery/hydroponics/AltClick(mob/user)
@@ -809,7 +817,7 @@
desc = initial(desc) desc = initial(desc)
TRAY_NAME_UPDATE TRAY_NAME_UPDATE
if(self_sustaining) //No reason to pay for an empty tray. if(self_sustaining) //No reason to pay for an empty tray.
idle_power_usage = 0 update_use_power(NO_POWER_USE)
self_sustaining = FALSE self_sustaining = FALSE
update_appearance() update_appearance()

View File

@@ -32,6 +32,8 @@
/// The APCs power channel is automatically on. /// The APCs power channel is automatically on.
#define APC_CHANNEL_AUTO_ON 3 #define APC_CHANNEL_AUTO_ON 3
#define APC_CHANNEL_IS_ON(channel) (channel >= APC_CHANNEL_ON)
// APC autoset enums: // APC autoset enums:
/// The APC turns automated and manual power channels off. /// The APC turns automated and manual power channels off.
#define AUTOSET_FORCE_OFF 0 #define AUTOSET_FORCE_OFF 0
@@ -138,7 +140,7 @@
var/environ = APC_CHANNEL_AUTO_ON var/environ = APC_CHANNEL_AUTO_ON
var/operating = TRUE var/operating = TRUE
var/charging = APC_NOT_CHARGING var/charging = APC_NOT_CHARGING
var/chargemode = 1 var/chargemode = TRUE
var/chargecount = 0 var/chargecount = 0
var/locked = TRUE var/locked = TRUE
var/coverlocked = TRUE var/coverlocked = TRUE
@@ -158,6 +160,7 @@
var/beenhit = 0 // used for counting how many times it has been hit, used for Aliens at the moment var/beenhit = 0 // used for counting how many times it has been hit, used for Aliens at the moment
var/mob/living/silicon/ai/occupier = null var/mob/living/silicon/ai/occupier = null
var/transfer_in_progress = FALSE //Is there an AI being transferred out of us? var/transfer_in_progress = FALSE //Is there an AI being transferred out of us?
///buffer state that makes apcs not shut off channels immediately as long as theres some power left, effect visible in apcs only slowly losing power
var/longtermpower = 10 var/longtermpower = 10
var/auto_name = FALSE var/auto_name = FALSE
var/failure_timer = 0 var/failure_timer = 0
@@ -1281,9 +1284,10 @@
force_update = TRUE force_update = TRUE
return return
lastused_light = area.power_usage[AREA_USAGE_LIGHT] + area.power_usage[AREA_USAGE_STATIC_LIGHT] //dont use any power from that channel if we shut that power channel off
lastused_equip = area.power_usage[AREA_USAGE_EQUIP] + area.power_usage[AREA_USAGE_STATIC_EQUIP] lastused_light = APC_CHANNEL_IS_ON(lighting) ? area.power_usage[AREA_USAGE_LIGHT] + area.power_usage[AREA_USAGE_STATIC_LIGHT] : 0
lastused_environ = area.power_usage[AREA_USAGE_ENVIRON] + area.power_usage[AREA_USAGE_STATIC_ENVIRON] lastused_equip = APC_CHANNEL_IS_ON(equipment) ? area.power_usage[AREA_USAGE_EQUIP] + area.power_usage[AREA_USAGE_STATIC_EQUIP] : 0
lastused_environ = APC_CHANNEL_IS_ON(environ) ? area.power_usage[AREA_USAGE_ENVIRON] + area.power_usage[AREA_USAGE_STATIC_ENVIRON] : 0
area.clear_usage() area.clear_usage()
lastused_total = lastused_light + lastused_equip + lastused_environ lastused_total = lastused_light + lastused_equip + lastused_environ
@@ -1447,17 +1451,18 @@
* - [AUTOSET_OFF]: The APC turns automatic channels off. * - [AUTOSET_OFF]: The APC turns automatic channels off.
*/ */
/obj/machinery/power/apc/proc/autoset(val, on) /obj/machinery/power/apc/proc/autoset(val, on)
if(on == AUTOSET_FORCE_OFF) switch(on)
if(val == APC_CHANNEL_ON) // if on, return off if(AUTOSET_FORCE_OFF)
return APC_CHANNEL_OFF if(val == APC_CHANNEL_ON) // if on, return off
else if(val == APC_CHANNEL_AUTO_ON) // if auto-on, return auto-off return APC_CHANNEL_OFF
return APC_CHANNEL_AUTO_OFF else if(val == APC_CHANNEL_AUTO_ON) // if auto-on, return auto-off
else if(on == AUTOSET_ON) return APC_CHANNEL_AUTO_OFF
if(val == APC_CHANNEL_AUTO_OFF) // if auto-off, return auto-on if(AUTOSET_ON)
return APC_CHANNEL_AUTO_ON if(val == APC_CHANNEL_AUTO_OFF) // if auto-off, return auto-on
else if(on == AUTOSET_OFF) return APC_CHANNEL_AUTO_ON
if(val == APC_CHANNEL_AUTO_ON) // if auto-on, return auto-off if(AUTOSET_OFF)
return APC_CHANNEL_AUTO_OFF if(val == APC_CHANNEL_AUTO_ON) // if auto-on, return auto-off
return APC_CHANNEL_AUTO_OFF
return val return val
/** /**

View File

@@ -294,7 +294,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
/obj/machinery/gravity_generator/main/proc/set_state(new_state) /obj/machinery/gravity_generator/main/proc/set_state(new_state)
charging_state = POWER_IDLE charging_state = POWER_IDLE
on = new_state on = new_state
use_power = on ? ACTIVE_POWER_USE : IDLE_POWER_USE update_use_power(on ? ACTIVE_POWER_USE : IDLE_POWER_USE)
// Sound the alert if gravity was just enabled or disabled. // Sound the alert if gravity was just enabled or disabled.
var/alert = FALSE var/alert = FALSE
if(SSticker.IsRoundInProgress()) if(SSticker.IsRoundInProgress())

View File

@@ -39,10 +39,10 @@
/obj/machinery/computer/monitor/process() /obj/machinery/computer/monitor/process()
if(!get_powernet()) if(!get_powernet())
use_power = IDLE_POWER_USE update_use_power(IDLE_POWER_USE)
search() search()
else else
use_power = ACTIVE_POWER_USE update_use_power(ACTIVE_POWER_USE)
record() record()
/obj/machinery/computer/monitor/proc/search() //keep in sync with /datum/computer_file/program/power_monitor's version /obj/machinery/computer/monitor/proc/search() //keep in sync with /datum/computer_file/program/power_monitor's version

View File

@@ -79,7 +79,7 @@
// returns true if the area has power on given channel (or doesn't require power). // returns true if the area has power on given channel (or doesn't require power).
// defaults to power_channel // defaults to power_channel
/obj/machinery/proc/powered(chan = -1) // defaults to power_channel /obj/machinery/proc/powered(chan = power_channel)
if(!loc) if(!loc)
return FALSE return FALSE
if(!use_power) if(!use_power)
@@ -88,18 +88,13 @@
var/area/A = get_area(src) // make sure it's in an area var/area/A = get_area(src) // make sure it's in an area
if(!A) if(!A)
return FALSE // if not, then not powered return FALSE // if not, then not powered
if(chan == -1)
chan = power_channel
return A.powered(chan) // return power status of the area return A.powered(chan) // return power status of the area
// increment the power usage stats for an area // increment the power usage stats for an area
/obj/machinery/proc/use_power(amount, chan = -1) // defaults to power_channel /obj/machinery/proc/use_power(amount, chan = power_channel)
var/area/A = get_area(src) // make sure it's in an area var/area/A = get_area(src) // make sure it's in an area
if(!A) A?.use_power(amount, chan)
return
if(chan == -1)
chan = power_channel
A.use_power(amount, chan)
/** /**
* An alternative to 'use_power', this proc directly costs the APC in direct charge, as opposed to being calculated periodically. * An alternative to 'use_power', this proc directly costs the APC in direct charge, as opposed to being calculated periodically.
@@ -154,9 +149,7 @@
/obj/machinery/proc/addStaticPower(value, powerchannel) /obj/machinery/proc/addStaticPower(value, powerchannel)
var/area/A = get_area(src) var/area/A = get_area(src)
if(!A) A?.addStaticPower(value, powerchannel)
return
A.addStaticPower(value, powerchannel)
/obj/machinery/proc/removeStaticPower(value, powerchannel) /obj/machinery/proc/removeStaticPower(value, powerchannel)
addStaticPower(-value, powerchannel) addStaticPower(-value, powerchannel)

View File

@@ -80,7 +80,7 @@
//see if there's a surplus of power remaining in the powernet and stores unused power in the SMES //see if there's a surplus of power remaining in the powernet and stores unused power in the SMES
netexcess = avail - load netexcess = avail - load
if(netexcess > 100 && nodes?.len) // if there was excess power last cycle if(netexcess > 100 && length(nodes)) // if there was excess power last cycle
for(var/obj/machinery/power/smes/S in nodes) // find the SMESes in the network 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 S.restore() // and restore some of the power that was used

View File

@@ -69,7 +69,7 @@
toggle_power() toggle_power()
user.visible_message(span_notice("[user.name] turns the [src.name] [active? "on":"off"]."), \ user.visible_message(span_notice("[user.name] turns the [src.name] [active? "on":"off"]."), \
span_notice("You turn the [src.name] [active? "on":"off"].")) span_notice("You turn the [src.name] [active? "on":"off"]."))
var/datum/gas_mixture/tank_mix = loaded_tank.return_air() var/datum/gas_mixture/tank_mix = loaded_tank?.return_air()
var/fuel var/fuel
if(loaded_tank) if(loaded_tank)
fuel = tank_mix.gases[/datum/gas/plasma] fuel = tank_mix.gases[/datum/gas/plasma]

View File

@@ -67,12 +67,12 @@
/obj/machinery/power/emitter/ctf /obj/machinery/power/emitter/ctf
name = "Energy Cannon" name = "Energy Cannon"
active = TRUE active = TRUE
active_power_usage = FALSE active_power_usage = 0
idle_power_usage = FALSE idle_power_usage = 0
locked = TRUE locked = TRUE
req_access_txt = "100" req_access_txt = "100"
welded = TRUE welded = TRUE
use_power = FALSE use_power = NO_POWER_USE
/obj/machinery/power/emitter/Initialize() /obj/machinery/power/emitter/Initialize()
. = ..() . = ..()
@@ -110,7 +110,7 @@
fire_delay = fire_shoot_delay fire_delay = fire_shoot_delay
for(var/obj/item/stock_parts/manipulator/manipulator in component_parts) for(var/obj/item/stock_parts/manipulator/manipulator in component_parts)
power_usage -= 50 * manipulator.rating power_usage -= 50 * manipulator.rating
active_power_usage = power_usage update_mode_power_usage(ACTIVE_POWER_USE, power_usage)
/obj/machinery/power/emitter/examine(mob/user) /obj/machinery/power/emitter/examine(mob/user)
. = ..() . = ..()

View File

@@ -9,7 +9,7 @@
icon_state = "mixer0" icon_state = "mixer0"
icon_keyboard = null icon_keyboard = null
base_icon_state = "mixer" base_icon_state = "mixer"
use_power = TRUE use_power = IDLE_POWER_USE
idle_power_usage = 20 idle_power_usage = 20
resistance_flags = ACID_PROOF resistance_flags = ACID_PROOF
circuit = /obj/item/circuitboard/computer/pandemic circuit = /obj/item/circuitboard/computer/pandemic

View File

@@ -188,7 +188,7 @@
return return
calcsuccess() calcsuccess()
use_power(MACHINE_OPERATION * power_saver) //This thing should eat your APC battery if you're not careful. use_power(MACHINE_OPERATION * power_saver) //This thing should eat your APC battery if you're not careful.
use_power = IDLE_POWER_USE //Machine shuts off after use to prevent spam and look better visually. update_use_power(IDLE_POWER_USE) //Machine shuts off after use to prevent spam and look better visually.
update_appearance() update_appearance()
if("amount") if("amount")
var/input = text2num(params["amount"]) var/input = text2num(params["amount"])
@@ -196,9 +196,9 @@
banking_amount = input banking_amount = input
if("toggle_power") if("toggle_power")
if(use_power == ACTIVE_POWER_USE) if(use_power == ACTIVE_POWER_USE)
use_power = IDLE_POWER_USE update_use_power(IDLE_POWER_USE)
else else
use_power = ACTIVE_POWER_USE update_use_power(ACTIVE_POWER_USE)
update_appearance() update_appearance()
if("account_reset") if("account_reset")
if(use_power == IDLE_POWER_USE) if(use_power == IDLE_POWER_USE)

View File

@@ -229,7 +229,7 @@
name = "luxury shuttle ticket field" name = "luxury shuttle ticket field"
density = FALSE //allows shuttle airlocks to close, nothing but an approved passenger gets past CanPass density = FALSE //allows shuttle airlocks to close, nothing but an approved passenger gets past CanPass
locked = TRUE locked = TRUE
use_power = FALSE use_power = NO_POWER_USE
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
var/threshold = 500 var/threshold = 500
var/static/list/approved_passengers = list() var/static/list/approved_passengers = list()

View File

@@ -92,7 +92,7 @@
base_icon_state = "sat" base_icon_state = "sat"
anchored = FALSE anchored = FALSE
density = TRUE density = TRUE
use_power = FALSE use_power = NO_POWER_USE
var/mode = "NTPROBEV0.8" var/mode = "NTPROBEV0.8"
var/active = FALSE var/active = FALSE
var/static/gid = 0 var/static/gid = 0

View File

@@ -185,7 +185,7 @@
*/ */
/obj/machinery/mecha_part_fabricator/proc/on_start_printing() /obj/machinery/mecha_part_fabricator/proc/on_start_printing()
add_overlay("fab-active") add_overlay("fab-active")
use_power = ACTIVE_POWER_USE update_use_power(ACTIVE_POWER_USE)
/** /**
* Intended to be called when the exofab has stopped working and is no longer printing items. * Intended to be called when the exofab has stopped working and is no longer printing items.
@@ -194,7 +194,7 @@
*/ */
/obj/machinery/mecha_part_fabricator/proc/on_finish_printing() /obj/machinery/mecha_part_fabricator/proc/on_finish_printing()
cut_overlay("fab-active") cut_overlay("fab-active")
use_power = IDLE_POWER_USE update_use_power(IDLE_POWER_USE)
desc = initial(desc) desc = initial(desc)
process_queue = FALSE process_queue = FALSE

View File

@@ -255,10 +255,10 @@ const AirAlarmControlThresholds = (props, context) => {
<thead> <thead>
<tr> <tr>
<td /> <td />
<td className="color-bad">min2</td> <td className="color-bad">hazard_min</td>
<td className="color-average">min1</td> <td className="color-average">warning_min</td>
<td className="color-average">max1</td> <td className="color-average">warning_max</td>
<td className="color-bad">max2</td> <td className="color-bad">hazard_max</td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>