From 62815b797fa38c01b5293045763536fe4698fe8e Mon Sep 17 00:00:00 2001 From: PigeonVerde322 Date: Sun, 14 Jul 2024 15:21:23 +0200 Subject: [PATCH 01/12] Recoup of #9968 --- beestation.dme | 1 + .../__DEFINES/atmospherics/atmos_machinery.dm | 18 + code/__DEFINES/dcs/signals/signals_area.dm | 4 + .../__DEFINES/important_recursive_contents.dm | 2 + code/__DEFINES/machines.dm | 8 +- code/__DEFINES/power/apc_defines.dm | 4 +- code/__DEFINES/traits.dm | 8 + code/controllers/subsystem/machines.dm | 34 +- code/game/area/areas.dm | 31 +- code/game/atoms.dm | 6 +- code/game/atoms_movable.dm | 18 + code/game/machinery/Beacon.dm | 4 +- code/game/machinery/_machinery.dm | 392 ++++++++++++------ code/game/machinery/cell_charger.dm | 8 +- code/game/machinery/dish_drive.dm | 10 +- code/game/machinery/hologram.dm | 43 +- code/game/machinery/launch_pad.dm | 6 +- code/game/machinery/recharger.dm | 3 +- code/game/machinery/rechargestation.dm | 4 +- code/game/machinery/stasis.dm | 8 +- code/modules/NTNet/relays.dm | 6 +- .../atmospherics/machinery/airalarm.dm | 360 ++++++++-------- .../components/unary_devices/thermomachine.dm | 6 +- .../components/unary_devices/vent_scrubber.dm | 58 +-- .../atmospherics/machinery/other/miner.dm | 10 +- .../machinery/portable/scrubber.dm | 4 +- .../kitchen_machinery/smartfridge.dm | 2 + code/modules/holodeck/computer.dm | 4 +- code/modules/hydroponics/hydroponics.dm | 13 + code/modules/power/apc/apc_main.dm | 3 +- code/modules/power/gravitygenerator.dm | 2 +- code/modules/power/monitor.dm | 4 +- code/modules/power/power.dm | 69 ++- code/modules/power/powernet.dm | 2 +- code/modules/power/singularity/emitter.dm | 8 +- .../reagents/chemistry/machinery/pandemic.dm | 2 +- code/modules/station_goals/shield.dm | 2 +- tgui/packages/tgui/interfaces/AirAlarm.js | 8 +- 38 files changed, 739 insertions(+), 436 deletions(-) create mode 100644 code/__DEFINES/atmospherics/atmos_machinery.dm diff --git a/beestation.dme b/beestation.dme index e2ee4144549e0..501cb2e8360a8 100644 --- a/beestation.dme +++ b/beestation.dme @@ -192,6 +192,7 @@ #include "code\__DEFINES\xenoartifact_materials.dm" #include "code\__DEFINES\xenobiology.dm" #include "code\__DEFINES\zmimic.dm" +#include "code\__DEFINES\atmospherics\atmos_machinery.dm" #include "code\__DEFINES\dcs\flags.dm" #include "code\__DEFINES\dcs\helpers.dm" #include "code\__DEFINES\dcs\signals.dm" diff --git a/code/__DEFINES/atmospherics/atmos_machinery.dm b/code/__DEFINES/atmospherics/atmos_machinery.dm new file mode 100644 index 0000000000000..e5f6612a0d097 --- /dev/null +++ b/code/__DEFINES/atmospherics/atmos_machinery.dm @@ -0,0 +1,18 @@ +/* FOR FUTURE USE!! +// Air alarm buildstage [/obj/machinery/airalarm/buildstage] +/// Air alarm missing circuit +#define AIR_ALARM_BUILD_NO_CIRCUIT 0 +/// Air alarm has circuit but is missing wires +#define AIR_ALARM_BUILD_NO_WIRES 1 +/// Air alarm has all components but isn't completed +#define AIR_ALARM_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 diff --git a/code/__DEFINES/dcs/signals/signals_area.dm b/code/__DEFINES/dcs/signals/signals_area.dm index 077917470f361..36256c3100d5b 100644 --- a/code/__DEFINES/dcs/signals/signals_area.dm +++ b/code/__DEFINES/dcs/signals/signals_area.dm @@ -10,3 +10,7 @@ ///! from base of area/Exited(): (atom/movable/M) #define COMSIG_AREA_EXITED "area_exited" +///from base of area/Entered(): (area/new_area). Sent to "area-sensitive" movables, see __DEFINES/traits.dm for info. +#define COMSIG_ENTER_AREA "enter_area" +///from base of area/Exited(): (area). Sent to "area-sensitive" movables, see __DEFINES/traits.dm for info. +#define COMSIG_EXIT_AREA "exit_area" diff --git a/code/__DEFINES/important_recursive_contents.dm b/code/__DEFINES/important_recursive_contents.dm index 62be5b38e5398..f1dc0bd3ea182 100644 --- a/code/__DEFINES/important_recursive_contents.dm +++ b/code/__DEFINES/important_recursive_contents.dm @@ -1,2 +1,4 @@ +///the area channel of the important_recursive_contents list, everything in here will be sent a signal when their last holding object changes areas +#define RECURSIVE_CONTENTS_AREA_SENSITIVE "recursive_contents_area_sensitive" ///the hearing channel of the important_recursive_contents list, everything in here will count as a hearing atom #define RECURSIVE_CONTENTS_HEARING_SENSITIVE "recursive_contents_hearing_sensitive" diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm index f1c3ec8771334..52c49c09ad24e 100644 --- a/code/__DEFINES/machines.dm +++ b/code/__DEFINES/machines.dm @@ -3,19 +3,23 @@ #define AREA_USAGE_EQUIP 1 #define AREA_USAGE_LIGHT 2 #define AREA_USAGE_ENVIRON 3 -#define AREA_USAGE_STATIC_EQUIP 4 -#define AREA_USAGE_STATIC_LIGHT 5 +#define AREA_USAGE_STATIC_EQUIP 4 +#define AREA_USAGE_STATIC_LIGHT 5 #define AREA_USAGE_STATIC_ENVIRON 6 #define AREA_USAGE_LEN AREA_USAGE_STATIC_ENVIRON // largest idx + /// Index of the first dynamic usage channel #define AREA_USAGE_DYNAMIC_START AREA_USAGE_EQUIP /// Index of the last dynamic usage channel #define AREA_USAGE_DYNAMIC_END AREA_USAGE_ENVIRON + /// Index of the first static usage channel #define AREA_USAGE_STATIC_START AREA_USAGE_STATIC_EQUIP /// Index of the last static usage channel #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 #define NO_POWER_USE 0 diff --git a/code/__DEFINES/power/apc_defines.dm b/code/__DEFINES/power/apc_defines.dm index 47673593cc287..6f6662094f851 100644 --- a/code/__DEFINES/power/apc_defines.dm +++ b/code/__DEFINES/power/apc_defines.dm @@ -14,8 +14,8 @@ /// The APCs cover is missing. #define APC_COVER_REMOVED 2 -// !NOT IMPLEMENTED! APC visuals -/// Pixel offset of the APC from the floor turf +// !NOT IMPLEMENTED! APC visuals +/// Pixel offset of the APC from the floor turf //#define APC_PIXEL_OFFSET 25 // APC charging status: diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 013482e9d1af6..0289d8a69dfad 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -287,6 +287,14 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_HEARING_SENSITIVE "hearing_sensitive" +//important_recursive_contents traits +/* + * Used for movables that need to be updated, via COMSIG_ENTER_AREA and COMSIG_EXIT_AREA, when transitioning areas. + * Use [/atom/movable/proc/become_area_sensitive(trait_source)] to properly enable it. How you remove it isn't as important. + */ +#define TRAIT_AREA_SENSITIVE "area-sensitive" +///every hearing sensitive atom has this trait + // item traits #define TRAIT_NODROP "nodrop" #define TRAIT_NO_STORAGE_INSERT "no_storage_insert" //cannot be inserted in a storage. diff --git a/code/controllers/subsystem/machines.dm b/code/controllers/subsystem/machines.dm index 05f9f48c8bdbe..bf63529969121 100644 --- a/code/controllers/subsystem/machines.dm +++ b/code/controllers/subsystem/machines.dm @@ -20,24 +20,24 @@ SUBSYSTEM_DEF(machines) .["custom"] = cust /datum/controller/subsystem/machines/proc/makepowernets() - for(var/datum/powernet/PN in powernets) - qdel(PN) + for(var/datum/powernet/power_network as anything in powernets) + qdel(power_network) powernets.Cut() - for(var/obj/structure/cable/PC in GLOB.cable_list) - if(!PC.powernet) - var/datum/powernet/NewPN = new() - NewPN.add_cable(PC) - propagate_network(PC,PC.powernet) - -/datum/controller/subsystem/machines/stat_entry() - . = ..("M:[processing.len]|PN:[powernets.len]") + for(var/obj/structure/cable/power_cable as anything in GLOB.cable_list) + if(!power_cable.powernet) + var/datum/powernet/new_powernet = new() + new_powernet.add_cable(power_cable) + propagate_network(power_cable, power_cable.powernet) +/datum/controller/subsystem/machines/stat_entry(msg) + msg = "M:[length(processing)]|PN:[length(powernets)]" + return ..() -/datum/controller/subsystem/machines/fire(resumed = 0) +/datum/controller/subsystem/machines/fire(resumed = FALSE) if (!resumed) - for(var/datum/powernet/Powernet in powernets) - Powernet.reset() //reset the power state. + for(var/datum/powernet/powernet as anything in powernets) + powernet.reset() //reset the power state. src.currentrun = processing.Copy() //cache for sanic speed (lists are references anyways) @@ -46,13 +46,9 @@ SUBSYSTEM_DEF(machines) while(currentrun.len) var/obj/machinery/thing = currentrun[currentrun.len] currentrun.len-- - if(!QDELETED(thing) && thing.process(wait * 0.1) != PROCESS_KILL) - if(thing.use_power) - thing.auto_use_power() //add back the power state - else + if(QDELETED(thing) || thing.process(wait * 0.1) == PROCESS_KILL) processing -= thing - if (!QDELETED(thing)) - thing.datum_flags &= ~DF_ISPROCESSING + thing.datum_flags &= ~DF_ISPROCESSING if (MC_TICK_CHECK) return diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index df6b03f7fdf85..50080cf245310 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -89,6 +89,12 @@ flags_1 = CAN_BE_DIRTY_1 + ///Used for Atmos air vents/Scrubbers + var/list/air_vent_names = list() + var/list/air_scrub_names = list() + var/list/air_vent_info = list() + var/list/air_scrub_info = list() + var/list/firedoors var/list/cameras var/list/firealarms @@ -516,12 +522,9 @@ 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. */ /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) update_appearance() - /** * Add a static amount of power load to an area * @@ -536,13 +539,27 @@ GLOBAL_LIST_EMPTY(teleportlocs) power_usage[powerchannel] += value /** - * Clear all power usage in area + * Remove a static amount of power load to an area + * + * 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 equipment, light and environment channels + * Clears all power used for the dynamic equipment, light and environment channels */ /area/proc/clear_usage() - for(var/i in AREA_USAGE_DYNAMIC_START to AREA_USAGE_DYNAMIC_END) - power_usage[i] = 0 + power_usage[AREA_USAGE_EQUIP] = 0 + power_usage[AREA_USAGE_LIGHT] = 0 + power_usage[AREA_USAGE_ENVIRON] = 0 /** * Add a power value amount to the stored used_x variables diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 7cac70720da31..bce7bcae68130 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -305,8 +305,10 @@ overlays.Cut() LAZYNULL(managed_overlays) - QDEL_NULL(light) - QDEL_NULL(ai_controller) + if(ai_controller) + QDEL_NULL(ai_controller) + if(light) + QDEL_NULL(light) for(var/i in targeted_by) var/mob/M = i diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index dc0a7bdb2b6a2..a26da068a4427 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1225,3 +1225,21 @@ for(var/channel in gone.important_recursive_contents) for(var/atom/movable/location as anything in nested_locs) LAZYREMOVEASSOC(location.important_recursive_contents, channel, gone.important_recursive_contents[channel]) + +///allows this movable to know when it has "entered" another area no matter how many movable atoms its stuffed into, uses important_recursive_contents +/atom/movable/proc/become_area_sensitive(trait_source = TRAIT_GENERIC) + if(!HAS_TRAIT(src, TRAIT_AREA_SENSITIVE)) + for(var/atom/movable/location as anything in get_nested_locs(src) + src) + LAZYADDASSOCLIST(location.important_recursive_contents, RECURSIVE_CONTENTS_AREA_SENSITIVE, src) + ADD_TRAIT(src, TRAIT_AREA_SENSITIVE, trait_source) + +///removes the area sensitive channel from the important_recursive_contents list of this and all nested locs containing us if there are no more source of the trait left +/atom/movable/proc/lose_area_sensitivity(trait_source = TRAIT_GENERIC) + if(!HAS_TRAIT(src, TRAIT_AREA_SENSITIVE)) + return + REMOVE_TRAIT(src, TRAIT_AREA_SENSITIVE, trait_source) + if(HAS_TRAIT(src, TRAIT_AREA_SENSITIVE)) + return + + for(var/atom/movable/location as anything in get_nested_locs(src) + src) + LAZYREMOVEASSOC(location.important_recursive_contents, RECURSIVE_CONTENTS_AREA_SENSITIVE, src) diff --git a/code/game/machinery/Beacon.dm b/code/game/machinery/Beacon.dm index da70d1f9afe2b..cfb6ecfd9df3b 100644 --- a/code/game/machinery/Beacon.dm +++ b/code/game/machinery/Beacon.dm @@ -3,9 +3,9 @@ icon = 'icons/obj/objects.dmi' icon_state = "floor_beaconf" name = "bluespace gigabeacon" - desc = "A device that draws power from bluespace and creates a permanent tracking beacon." + desc = "A self-powered device that draws power from bluespace and creates a permanent tracking beacon." layer = LOW_OBJ_LAYER - use_power = IDLE_POWER_USE + use_power = NO_POWER_USE //The gigabeacon should not fail if there's no power around! idle_power_usage = 0 var/obj/item/beacon/Beacon diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index ca03a01466159..46891315dafb2 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -1,84 +1,89 @@ -/* -Overview: - Used to create objects that need a per step proc call. Default definition of 'Initialize()' - stores a reference to src machine in global 'machines list'. Default definition - of 'Destroy' removes reference to src machine in global 'machines list'. - -Class Variables: - use_power (num) - current state of auto power use. - Possible Values: - NO_POWER_USE -- no auto power use - IDLE_POWER_USE -- machine is using power at its idle power level - ACTIVE_POWER_USE -- machine is using power at its active power level - - active_power_usage (num) - Value for the amount of power to use when in active power mode - - idle_power_usage (num) - Value for the amount of power to use when in idle power mode - - power_channel (num) - What channel to draw from when drawing power for power mode - Possible Values: - AREA_USAGE_EQUIP:0 -- Equipment Channel - AREA_USAGE_LIGHT:2 -- Lighting Channel - AREA_USAGE_ENVIRON:3 -- Environment Channel - - component_parts (list) - A list of component parts of machine used by frame based machines. - - machine_stat (bitflag) - Machine status bit flags. - Possible bit flags: - BROKEN -- Machine is broken - NOPOWER -- No power is being supplied to machine. - MAINT -- machine is currently under going maintenance. - EMPED -- temporary broken by EMP pulse - -Class Procs: - Initialize() 'game/machinery/machine.dm' - - Destroy() 'game/machinery/machine.dm' - - auto_use_power() 'game/machinery/machine.dm' - This proc determines how power mode power is deducted by the machine. - 'auto_use_power()' is called by the 'master_controller' game_controller every - tick. - - 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', - 'idle_power_usage', 'powered()', and 'use_power()' implement behavior. - - powered(chan = -1) 'modules/power/power.dm' - Checks to see if area that contains the object has power available for power - channel given in 'chan'. -1 defaults to power_channel - - use_power(amount, chan=-1) 'modules/power/power.dm' - Deducts 'amount' from the power channel 'chan' of the area that contains the object. - - power_change() 'modules/power/power.dm' - Called by the area that contains the object when ever that area under goes a - power state change (area runs out of power, or area channel is turned off). - - RefreshParts() 'game/machinery/machine.dm' - Called to refresh the variables in the machine that are contributed to by parts - contained in the component_parts list. (example: glass and material amounts for - the autolathe) - - Default definition does nothing. - - process() 'game/machinery/machine.dm' - Called by the 'machinery subsystem' once per machinery tick for each machine that is listed in its 'machines' list. - - process_atmos() - Called by the 'air subsystem' once per atmos tick for each machine that is listed in its 'atmos_machines' list. - - Compiled by Aygar -*/ +/** + * Machines in the world, such as computers, pipes, and airlocks. + * + *Overview: + * Used to create objects that need a per step proc call. Default definition of 'Initialize()' + * stores a reference to src machine in global 'machines list'. Default definition + * of 'Destroy' removes reference to src machine in global 'machines list'. + * + *Class Variables: + * use_power (num) + * current state of auto power use. + * Possible Values: + * NO_POWER_USE -- no auto power use + * IDLE_POWER_USE -- machine is using power at its idle power level + * ACTIVE_POWER_USE -- machine is using power at its active power level + * + * active_power_usage (num) + * Value for the amount of power to use when in active power mode + * + * idle_power_usage (num) + * Value for the amount of power to use when in idle power mode + * + * power_channel (num) + * What channel to draw from when drawing power for power mode + * Possible Values: + * AREA_USAGE_EQUIP:1 -- Equipment Channel + * AREA_USAGE_LIGHT:2 -- Lighting Channel + * AREA_USAGE_ENVIRON:3 -- Environment Channel + * + * component_parts (list) + * A list of component parts of machine used by frame based machines. + * + * machine_stat (bitflag) + * Machine status bit flags. + * Possible bit flags: + * BROKEN -- Machine is broken + * NOPOWER -- No power is being supplied to machine. + * MAINT -- machine is currently under going maintenance. + * EMPED -- temporary broken by EMP pulse + * + *Class Procs: + * Initialize() + * + * Destroy() + * + * update_mode_power_usage() + * updates the static_power_usage var of this machine and makes its static power usage from its area accurate. + * called after the idle or active power usage has been changed. + * + * 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. + * + * + * Default definition uses 'use_power', 'power_channel', 'active_power_usage', + * 'idle_power_usage', 'powered()', and 'use_power()' implement behavior. + * + * powered(chan = -1) 'modules/power/power.dm' + * Checks to see if area that contains the object has power available for power + * channel given in 'chan'. -1 defaults to power_channel + * + * use_power(amount, chan=-1) 'modules/power/power.dm' + * Deducts 'amount' from the power channel 'chan' of the area that contains the object. + * + * power_change() 'modules/power/power.dm' + * Called by the area that contains the object when ever that area under goes a + * power state change (area runs out of power, or area channel is turned off). + * + * RefreshParts() 'game/machinery/machine.dm' + * Called to refresh the variables in the machine that are contributed to by parts + * contained in the component_parts list. (example: glass and material amounts for + * the autolathe) + * + * Default definition does nothing. + * + * process() 'game/machinery/machine.dm' + * Called by the 'machinery subsystem' once per machinery tick for each machine that is listed in its 'machines' list. + * + * process_atmos() + * Called by the 'air subsystem' once per atmos tick for each machine that is listed in its 'atmos_machines' list. + * Compiled by Aygar + */ /obj/machinery name = "machinery" @@ -98,11 +103,16 @@ Class Procs: var/machine_stat = NONE var/use_power = IDLE_POWER_USE - //0 = dont run the auto - //1 = run auto, use idle - //2 = run auto, use active + //0 = dont use power + //1 = use idle_power_usage + //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 + ///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 + ///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 //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. @@ -166,6 +176,63 @@ Class Procs: 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_REF(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) SHOULD_CALL_PARENT(TRUE) @@ -182,20 +249,6 @@ Class Procs: var/datum/controller/subsystem/processing/subsystem = locate(subsystem_type) in Master.subsystems STOP_PROCESSING(subsystem, src) -/obj/machinery/LateInitialize() - . = ..() - power_change() - RegisterSignal(src, COMSIG_MOVABLE_ENTERED_AREA, PROC_REF(power_change)) - -/obj/machinery/Destroy() - GLOB.machines.Remove(src) - if(datum_flags & DF_ISPROCESSING) // A sizeable portion of machines stops processing before qdel - end_processing() - dump_inventory_contents() - QDEL_LIST(component_parts) - QDEL_NULL(circuit) - return ..() - /obj/machinery/proc/locate_machinery() return @@ -213,10 +266,12 @@ Class Procs: ///Called when the value of `machine_stat` changes, so we can react to it. /obj/machinery/proc/on_set_machine_stat(old_value) - if(old_value & (NOPOWER|BROKEN|MAINT)) - if(!(machine_stat & (NOPOWER|BROKEN|MAINT))) //From off to on. - set_is_operational(TRUE) - else if(machine_stat & (NOPOWER|BROKEN|MAINT)) //From on to off. + //From off to on. + if((old_value & (NOPOWER|BROKEN|MAINT)) && !(machine_stat & (NOPOWER|BROKEN|MAINT))) + set_is_operational(TRUE) + return + //From on to off. + if(machine_stat & (NOPOWER|BROKEN|MAINT)) set_is_operational(FALSE) /obj/machinery/emp_act(severity) @@ -295,7 +350,7 @@ Class Procs: living_mob.update_mobility() if(occupant == movable_atom) - occupant = null + set_occupant(null) /** * Puts passed object in to user's hand @@ -339,14 +394,119 @@ Class Procs: update_icon() ui_update() -/obj/machinery/proc/auto_use_power() - if(!powered(power_channel)) - return 0 - if(use_power == 1) - use_power(idle_power_usage,power_channel) - else if(use_power >= 2) - use_power(active_power_usage,power_channel) - return 1 +///updates the use_power var for this machine and updates its static power usage from its area to reflect the new value +/obj/machinery/proc/update_use_power(new_use_power) + SHOULD_CALL_PARENT(TRUE) + if(new_use_power == use_power) + return FALSE + + unset_static_power() + + 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 + +///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. /obj/machinery/proc/set_is_operational(new_value) @@ -582,7 +742,7 @@ Class Procs: /obj/machinery/run_obj_armor(damage_amount, damage_type, damage_flag = NONE, attack_dir) if(damage_flag == MELEE && damage_amount < damage_deflection) - return 0 + return FALSE return ..() /obj/machinery/proc/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I) @@ -596,8 +756,8 @@ Class Procs: panel_open = FALSE icon_state = icon_state_closed to_chat(user, "You close the maintenance hatch of [src].") - return 1 - return 0 + return TRUE + return FALSE /** * * turns: The amount of times to turn -90 degrees. Pointless to set this to anything above 4 @@ -608,8 +768,8 @@ Class Procs: I.play_tool_sound(src, 50) setDir(turn(dir,turns)) to_chat(user, "You rotate [src].") - return 1 - return 0 + return TRUE + return FALSE /obj/proc/can_be_unfasten_wrench(mob/user, silent) //if we can unwrench this object; returns SUCCESSFUL_UNFASTEN and FAILED_UNFASTEN, which are both TRUE, or CANT_UNFASTEN, which isn't. if(!(isfloorturf(loc) || istype(loc, /turf/open/indestructible)) && !anchored) diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index bd0a164f12229..cbede2a66c62c 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -126,7 +126,11 @@ if(charging.percent() >= 100) return - use_power(charge_rate * delta_time) - charging.give(charge_rate * delta_time) //this is 2558, efficient batteries exist + var/main_draw = use_power_from_net(charge_rate * delta_time, take_any = TRUE) //Pulls directly from the Powernet to dump into the cell + if(!main_draw) + return + charging.give(main_draw) + use_power(charge_rate / 100) //use a small bit for the charger itself, but power usage scales up with the part tier + //this is 2558, unfortunately, lead batteries are still a thing, sorry! update_icon() diff --git a/code/game/machinery/dish_drive.dm b/code/game/machinery/dish_drive.dm index bd5eb18709cb2..701f3ab0d8614 100644 --- a/code/game/machinery/dish_drive.dm +++ b/code/game/machinery/dish_drive.dm @@ -71,18 +71,14 @@ ..() /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 for(var/obj/item/stock_parts/S in component_parts) total_rating += S.rating if(total_rating >= 9) - active_power_usage = 0 - use_power = NO_POWER_USE + update_mode_power_usage(ACTIVE_POWER_USE, 0) else - idle_power_usage = max(0, idle_power_usage - total_rating) - active_power_usage = max(0, active_power_usage - total_rating) + update_mode_power_usage(IDLE_POWER_USE, max(0, initial(idle_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 if(board) suction_enabled = board.suction diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 1816e51b1d651..d1305d10ac5e3 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -341,13 +341,8 @@ Possible to do for anyone motivated enough: clear_holo(user) /obj/machinery/holopad/process() - if(LAZYLEN(masters)) - for(var/I in masters) - var/mob/living/master = I - var/mob/living/silicon/ai/AI = master - if(!istype(AI)) - AI = null - + if(LAZYLEN(masters)) //As someone in the original PR commented, the original code was indeed depressing + for(var/mob/living/master as anything in masters) if(!is_operational || !validate_user(master)) clear_holo(master) @@ -356,19 +351,25 @@ Possible to do for anyone motivated enough: ringing = FALSE - for(var/I in holo_calls) - var/datum/holocall/HC = I - if(HC.connected_holopad != src) - if(force_answer_call && world.time > (HC.call_start_time + (HOLOPAD_MAX_DIAL_TIME / 2))) - 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 + for(var/datum/holocall/holocall as anything in holo_calls) + if(holocall.connected_holopad == src) + continue - update_icon() + 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) var/mob/living/silicon/ai/AI = user @@ -436,8 +437,8 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ /obj/machinery/holopad/proc/SetLightsAndPower() var/total_users = LAZYLEN(masters) + LAZYLEN(holo_calls) - use_power = total_users > 0 ? ACTIVE_POWER_USE : IDLE_POWER_USE - active_power_usage = HOLOPAD_PASSIVE_POWER_USAGE + (HOLOGRAM_POWER_USAGE * total_users) + update_use_power(total_users > 0 ? ACTIVE_POWER_USE : IDLE_POWER_USE) + update_mode_power_usage(ACTIVE_POWER_USE, HOLOPAD_PASSIVE_POWER_USAGE + (HOLOGRAM_POWER_USAGE * total_users)) if(total_users || replay_mode) set_light(2) else diff --git a/code/game/machinery/launch_pad.dm b/code/game/machinery/launch_pad.dm index 543213f2a6616..be78b1cad939d 100644 --- a/code/game/machinery/launch_pad.dm +++ b/code/game/machinery/launch_pad.dm @@ -3,7 +3,7 @@ desc = "A bluespace pad able to thrust matter through bluespace, teleporting it to or from nearby locations." icon = 'icons/obj/telescience.dmi' icon_state = "lpad-idle" - use_power = TRUE + use_power = IDLE_POWER_USE idle_power_usage = 200 active_power_usage = 2500 hud_possible = list(DIAG_LAUNCHPAD_HUD) @@ -214,14 +214,14 @@ DEFINE_BUFFER_HANDLER(/obj/machinery/launchpad) investigate_log(log_msg.Join(), INVESTIGATE_TELESCI) updateDialog() -//Starts in the briefcase. Don't spawn this directly, or it will runtime when closing. +//Starts in the briefcase. Don't spawn this directly, or it will runtime when closing. Why this doorhickey even exists? When was the last time somoene *actually* used it? /obj/machinery/launchpad/briefcase name = "briefcase launchpad" desc = "A portable bluespace pad able to thrust matter through bluespace, teleporting it to or from nearby locations. Controlled via remote." icon_state = "blpad-idle" icon_teleport = "blpad-beam" anchored = FALSE - use_power = FALSE + use_power = IDLE_POWER_USE idle_power_usage = 0 active_power_usage = 0 teleport_speed = 20 diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 793ee1b7462f6..1e93d13043b04 100755 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -49,11 +49,12 @@ charging = new_charging if (new_charging) START_PROCESSING(SSmachines, src) + update_use_power(ACTIVE_POWER_USE) use_power = ACTIVE_POWER_USE using_power = TRUE update_appearance() else - use_power = IDLE_POWER_USE + update_use_power(IDLE_POWER_USE) using_power = FALSE update_appearance() diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 710e46fb019f7..ccff6a424f389 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -79,12 +79,12 @@ /obj/machinery/recharge_station/open_machine() . = ..() - use_power = IDLE_POWER_USE + update_use_power(IDLE_POWER_USE) /obj/machinery/recharge_station/close_machine() . = ..() 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) /obj/machinery/recharge_station/update_icon() diff --git a/code/game/machinery/stasis.dm b/code/game/machinery/stasis.dm index 0beaf9b54f289..721e62c3ca44d 100644 --- a/code/game/machinery/stasis.dm +++ b/code/game/machinery/stasis.dm @@ -124,12 +124,12 @@ playsound(src, 'sound/effects/spray.ogg', 5, TRUE, 2, frequency = freq) target.apply_status_effect(STATUS_EFFECT_STASIS, STASIS_MACHINE_EFFECT) target.ExtinguishMob() - use_power = ACTIVE_POWER_USE + update_use_power(ACTIVE_POWER_USE) /obj/machinery/stasis/proc/thaw_them(mob/living/target) target.remove_status_effect(STATUS_EFFECT_STASIS, STASIS_MACHINE_EFFECT) if(target == occupant) - use_power = IDLE_POWER_USE + update_use_power(IDLE_POWER_USE) /obj/machinery/stasis/post_buckle_mob(mob/living/L) if(!can_be_occupant(L)) @@ -146,8 +146,8 @@ update_icon() /obj/machinery/stasis/process() - if( !( occupant && isliving(occupant) && check_nap_violations() ) ) - use_power = IDLE_POWER_USE + if(!(occupant && isliving(occupant) && check_nap_violations())) + update_use_power(IDLE_POWER_USE) return var/mob/living/L_occupant = occupant if(stasis_running()) diff --git a/code/modules/NTNet/relays.dm b/code/modules/NTNet/relays.dm index a8f833016562d..74f43474814a8 100644 --- a/code/modules/NTNet/relays.dm +++ b/code/modules/NTNet/relays.dm @@ -66,11 +66,7 @@ icon_state = "bus_off" /obj/machinery/ntnet_relay/process(delta_time) - if(is_operational) - use_power = ACTIVE_POWER_USE - else - use_power = IDLE_POWER_USE - + update_use_power(is_operational ? ACTIVE_POWER_USE : IDLE_POWER_USE) update_icon() if(dos_overload > 0) diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index c72272eea7584..0b871012cc30a 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -1,37 +1,42 @@ /datum/tlv - var/min2 - var/min1 - var/max1 - var/max2 + var/warning_min + var/warning_max + var/hazard_min + var/hazard_max /datum/tlv/New(min2 as num, min1 as num, max1 as num, max2 as num) - if(min2) src.min2 = min2 - if(min1) src.min1 = min1 - if(max1) src.max1 = max1 - if(max2) src.max2 = max2 - -/datum/tlv/proc/get_danger_level(val as num) - if(max2 != -1 && val >= max2) - return 2 - if(min2 != -1 && val <= min2) - return 2 - if(max1 != -1 && val >= max1) - return 1 - if(min1 != -1 && val <= min1) - return 1 - return 0 + if(min2) + hazard_min = min2 + if(min1) + warning_min = min1 + if(max1) + warning_max = max1 + if(max2) + hazard_max = max2 + +/datum/tlv/proc/get_danger_level(val) + if(hazard_max != TLV_DONT_CHECK && val >= hazard_max) + return TLV_OUTSIDE_HAZARD_LIMIT + if(hazard_min != TLV_DONT_CHECK && val <= hazard_min) + return TLV_OUTSIDE_HAZARD_LIMIT + if(warning_max != TLV_DONT_CHECK && val >= warning_max) + return TLV_OUTSIDE_WARNING_LIMIT + if(warning_min != TLV_DONT_CHECK && val <= warning_min) + return TLV_OUTSIDE_WARNING_LIMIT + + return TLV_NO_DANGER /datum/tlv/no_checks - min2 = -1 - min1 = -1 - max1 = -1 - max2 = -1 + hazard_min = TLV_DONT_CHECK + warning_min = TLV_DONT_CHECK + warning_max = TLV_DONT_CHECK + hazard_max = TLV_DONT_CHECK /datum/tlv/dangerous - min2 = -1 - min1 = -1 - max1 = 0.2 - max2 = 0.5 + hazard_min = TLV_DONT_CHECK + warning_min = TLV_DONT_CHECK + warning_max = 0.2 + hazard_max = 0.5 /obj/item/electronics/airalarm name = "air alarm electronics" @@ -74,7 +79,6 @@ clicksound = 'sound/machines/terminal_select.ogg' layer = ABOVE_WINDOW_LAYER - var/danger_level = 0 var/mode = AALARM_MODE_SCRUBBING @@ -89,112 +93,27 @@ ///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/static/list/atmos_connections = list(COMSIG_TURF_EXPOSE = PROC_REF(check_air_dangerlevel)) + var/list/TLV = list( // Breathable air. - "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa. Values are min2, min1, max1, max2 - "temperature" = new/datum/tlv(T0C, T0C+10, T0C+40, T0C+66), + "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(T0C, T0C+10, T0C+40, T0C+66), GAS_O2 = new/datum/tlv(16, 19, 40, 50), // Partial pressure, kpa GAS_N2 = new/datum/tlv(-1, -1, 1000, 1000), - GAS_CO2 = new/datum/tlv(-1, -1, 5, 10), - GAS_PLASMA = new/datum/tlv/dangerous, - GAS_NITROUS = new/datum/tlv/dangerous, - GAS_BZ = new/datum/tlv/dangerous, - GAS_HYPERNOB = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic - GAS_H2O = new/datum/tlv/dangerous, - GAS_TRITIUM = new/datum/tlv/dangerous, - GAS_STIMULUM = new/datum/tlv/dangerous, - GAS_NITRYL = new/datum/tlv/dangerous, - GAS_PLUOXIUM = new/datum/tlv(-1, -1, 5, 6), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires + GAS_CO2 = new/datum/tlv(-1, -1, 5, 10), + GAS_PLASMA = new/datum/tlv/dangerous, + GAS_NITROUS = new/datum/tlv/dangerous, + GAS_BZ = new/datum/tlv/dangerous, + GAS_HYPERNOB = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic + GAS_H2O = new/datum/tlv/dangerous, + GAS_TRITIUM = new/datum/tlv/dangerous, + GAS_STIMULUM = new/datum/tlv/dangerous, + GAS_NITRYL = new/datum/tlv/dangerous, + GAS_PLUOXIUM = new/datum/tlv(-1, -1, 5, 6), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires ) -/obj/machinery/airalarm/server // No checks here. - TLV = list( - "pressure" = new/datum/tlv/no_checks, - "temperature" = new/datum/tlv/no_checks, - GAS_O2 = new/datum/tlv/no_checks, - GAS_N2 = new/datum/tlv/no_checks, - GAS_CO2 = new/datum/tlv/no_checks, - GAS_PLASMA = new/datum/tlv/no_checks, - GAS_NITROUS = new/datum/tlv/no_checks, - GAS_BZ = new/datum/tlv/no_checks, - GAS_HYPERNOB = new/datum/tlv/no_checks, - GAS_H2O = new/datum/tlv/no_checks, - GAS_TRITIUM = new/datum/tlv/no_checks, - GAS_STIMULUM = new/datum/tlv/no_checks, - GAS_NITRYL = new/datum/tlv/no_checks, - GAS_PLUOXIUM = new/datum/tlv/no_checks - ) - -/obj/machinery/airalarm/kitchen_cold_room // Kitchen cold rooms start off at -20°C or 253.15 K. - 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(T0C-273.15, T0C-80, T0C-10, T0C+10), - GAS_O2 = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa - GAS_N2 = new/datum/tlv(-1, -1, 1000, 1000), - GAS_CO2 = new/datum/tlv(-1, -1, 5, 10), - GAS_PLASMA = new/datum/tlv/dangerous, - GAS_NITROUS = new/datum/tlv/dangerous, - GAS_BZ = new/datum/tlv/dangerous, - GAS_HYPERNOB = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic - GAS_H2O = new/datum/tlv/dangerous, - GAS_TRITIUM = new/datum/tlv/dangerous, - GAS_STIMULUM = new/datum/tlv/dangerous, - GAS_NITRYL = new/datum/tlv/dangerous, - GAS_PLUOXIUM = new/datum/tlv(-1, -1, 1000, 1000) // Unlike oxygen, pluoxium does not fuel plasma/tritium fires - ) - -/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_TOX, ACCESS_TOX_STORAGE) - -/obj/machinery/airalarm/all_access - name = "all-access air alarm" - desc = "This particular atmospherics 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_names = list() - var/list/air_scrub_names = list() - var/list/air_vent_info = list() - var/list/air_scrub_info = list() - -/obj/machinery/airalarm/Initialize(mapload, ndir, nbuild) - . = ..() +/obj/machinery/airalarm/New(mapload, ndir, nbuild) + ..() wires = new /datum/wires/airalarm(src) if(ndir) setDir(ndir) @@ -211,12 +130,6 @@ alarm_manager = new(src) update_appearance() - set_frequency(frequency) - AddComponent(/datum/component/usb_port, list( - /obj/item/circuit_component/air_alarm, - )) - GLOB.zclear_atoms += src - /obj/machinery/airalarm/Destroy() SSradio.remove_object(src, frequency) QDEL_NULL(wires) @@ -224,6 +137,16 @@ GLOB.zclear_atoms -= src return ..() +/obj/machinery/airalarm/Initialize(mapload) + . = ..() + set_frequency(frequency) + AddElement(/datum/element/connect_loc, atmos_connections) + AddComponent(/datum/component/usb_port, list( + /obj/item/circuit_component/air_alarm, + )) + GLOB.zclear_atoms += src + + /obj/machinery/airalarm/examine(mob/user) . = ..() switch(buildstage) @@ -351,27 +274,27 @@ selected = TLV["pressure"] 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" = "min1", "selected" = selected.min1)) - thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "max1", "selected" = selected.max1)) - thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "max2", "selected" = selected.max2)) + thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "hazard_min", "selected" = selected.hazard_min)) + thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "warning_min", "selected" = selected.warning_min)) + thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "warning_max", "selected" = selected.warning_max)) + thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "hazard_max", "selected" = selected.hazard_max)) selected = TLV["temperature"] 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" = "min1", "selected" = selected.min1)) - thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max1", "selected" = selected.max1)) - thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max2", "selected" = selected.max2)) + thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "hazard_min", "selected" = selected.hazard_min)) + thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "warning_min", "selected" = selected.warning_min)) + thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "warning_max", "selected" = selected.warning_max)) + thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "hazard_max", "selected" = selected.hazard_max)) for(var/gas_id in GLOB.gas_data.names) if(!(gas_id in TLV)) // We're not interested in this gas, it seems. continue selected = TLV[gas_id] thresholds += list(list("name" = GLOB.gas_data.names[gas_id], "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" = "min1", "selected" = selected.min1)) - thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "max1", "selected" = selected.max1)) - 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_min", "selected" = selected.hazard_min)) + 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" = "warning_max", "selected" = selected.warning_max)) + thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "hazard_max", "selected" = selected.hazard_max)) data["thresholds"] = thresholds return data @@ -422,7 +345,10 @@ tlv.vars[name] = -1 else 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(" threshold 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.return_temperature()) . = TRUE if("mode") mode = text2num(params["mode"]) @@ -456,16 +382,16 @@ /obj/machinery/airalarm/proc/shock(mob/user, prb) if((machine_stat & (NOPOWER))) // unpowered, no shock - return 0 + return TRUE if(!prob(prb)) - return 0 //you lucked out, no shock for you + return FALSE //you lucked out, no shock for you var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread s.set_up(5, 1, src) s.start() //sparks always. if (electrocute_mob(user, get_area(src), src, 1, TRUE)) - return 1 + return TRUE else - return 0 + return FALSE /obj/machinery/airalarm/proc/set_frequency(new_frequency) SSradio.remove_object(src, frequency) @@ -474,7 +400,7 @@ /obj/machinery/airalarm/proc/send_signal(target, list/command, atom/user)//sends signal 'command' to 'target'. Returns 0 if no radio connection, 1 otherwise if(!radio_connection) - return 0 + return FALSE var/datum/signal/signal = new(command) signal.data["tag"] = target @@ -482,7 +408,7 @@ signal.data["user"] = user radio_connection.post_signal(src, signal, RADIO_FROM_AIRALARM) - return 1 + return TRUE /obj/machinery/airalarm/proc/get_mode_name(mode_value) switch(mode_value) @@ -643,42 +569,46 @@ if(2) icon_state = "alarm1" -/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) return - var/turf/location = get_turf(src) - if(!location) - return + var/datum/tlv/current_tlv + //cache for REALLY fast speed (lists are references anyways) + var/list/cached_tlv = TLV var/datum/tlv/cur_tlv - var/datum/gas_mixture/environment = location.return_air() - var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.return_temperature() / environment.return_volume() + var/partial_pressure = R_IDEAL_GAS_EQUATION * exposed_temperature / environment.return_volume() - cur_tlv = TLV["pressure"] + current_tlv = cached_tlv["pressure"] var/environment_pressure = environment.return_pressure() var/pressure_dangerlevel = cur_tlv.get_danger_level(environment_pressure) - cur_tlv = TLV["temperature"] - var/temperature_dangerlevel = cur_tlv.get_danger_level(environment.return_temperature()) + current_tlv = cached_tlv["temperature"] + var/temperature_dangerlevel = current_tlv.get_danger_level(exposed_temperature) var/gas_dangerlevel = 0 for(var/gas_id in environment.get_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 - cur_tlv = TLV[gas_id] - gas_dangerlevel = max(gas_dangerlevel, cur_tlv.get_danger_level(environment.get_moles(gas_id) * partial_pressure)) + current_tlv = cached_tlv[gas_id] + gas_dangerlevel = max(gas_dangerlevel, current_tlv.get_danger_level(environment.get_moles(gas_id) * partial_pressure)) var/old_danger_level = danger_level danger_level = max(pressure_dangerlevel, temperature_dangerlevel, gas_dangerlevel) if(old_danger_level != danger_level) - apply_danger_level() + INVOKE_ASYNC(src, PROC_REF(apply_danger_level)) if(mode == AALARM_MODE_REPLACEMENT && environment_pressure < ONE_ATMOSPHERE * 0.05) mode = AALARM_MODE_SCRUBBING - apply_mode(src) - + INVOKE_ASYNC(src, PROC_REF(apply_mode), src) /obj/machinery/airalarm/proc/post_alert(alert_level) var/datum/radio_frequency/frequency = SSradio.return_frequency(alarm_frequency) @@ -856,6 +786,90 @@ new /obj/item/stack/cable_coil(loc, 3) qdel(src) +/**ALL OF THAT AIR ALARMS VARIATIONS RIGHT HERE :CLAP:*/ + +/obj/machinery/airalarm/server // No checks here. + TLV = list( + "pressure" = new/datum/tlv/no_checks, + "temperature" = new/datum/tlv/no_checks, + GAS_O2 = new/datum/tlv/no_checks, + GAS_N2 = new/datum/tlv/no_checks, + GAS_CO2 = new/datum/tlv/no_checks, + GAS_PLASMA = new/datum/tlv/no_checks, + GAS_NITROUS = new/datum/tlv/no_checks, + GAS_BZ = new/datum/tlv/no_checks, + GAS_HYPERNOB = new/datum/tlv/no_checks, + GAS_H2O = new/datum/tlv/no_checks, + GAS_TRITIUM = new/datum/tlv/no_checks, + GAS_STIMULUM = new/datum/tlv/no_checks, + GAS_NITRYL = new/datum/tlv/no_checks, + GAS_PLUOXIUM = new/datum/tlv/no_checks + ) + +/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/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 + ) + +/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_TOX, ACCESS_TOX_STORAGE) + +/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 + +/**end of air alarms variants **/ + /obj/item/circuit_component/air_alarm display_name = "Air Alarm" desc = "Controls levels of gases and their temperature as well as all vents and scrubbers in the room." @@ -927,10 +941,10 @@ return var/datum/tlv/settings = connected_alarm.TLV[options_map[current_option]] - settings.min2 = min_2 - settings.min1 = min_1 - settings.max1 = max_1 - settings.max2 = max_2 + settings.hazard_min = min_2 + settings.warning_min = min_1 + settings.warning_max = max_1 + settings.hazard_max = max_2 #undef AALARM_MODE_SCRUBBING #undef AALARM_MODE_VENTING diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index 41e2ce70afe5e..8b155d4eee30e 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm @@ -1,7 +1,6 @@ /obj/machinery/atmospherics/components/unary/thermomachine icon = 'icons/obj/atmospherics/components/thermomachine.dmi' icon_state = "freezer" - name = "Thermomachine" desc = "Heats or cools gas in connected pipes." @@ -11,8 +10,6 @@ layer = OBJ_LAYER circuit = /obj/item/circuitboard/machine/thermomachine - - pipe_flags = PIPING_ONE_PER_TURF var/icon_state_off = "freezer" @@ -191,14 +188,13 @@ return data /obj/machinery/atmospherics/components/unary/thermomachine/ui_act(action, params) - if(..()) return switch(action) if("power") 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) . = TRUE if("cooling") diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index 78f7434100d7f..e337df969d50b 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -21,7 +21,7 @@ var/filter_types = list(GAS_CO2, GAS_BZ) 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/frequency = FREQ_ATMOS_CONTROL @@ -47,22 +47,6 @@ adjacent_turfs.Cut() 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() cut_overlays() if(showpipe) @@ -79,7 +63,7 @@ icon_state = "scrub_off" return - if(scrubbing & SCRUBBING) + if(scrubbing == SCRUBBING) if(widenet) icon_state = "scrub_wide" else @@ -165,25 +149,28 @@ return TRUE -//There is no easy way for an object to be notified of changes to atmos can pass flags -// So we check every machinery process (2 seconds) +///There is no easy way for an object to be notified of changes to atmos can pass flags +///So we check every machinery process (2 seconds) /obj/machinery/atmospherics/components/unary/vent_scrubber/process() if(widenet) check_turfs() -//we populate a list of turfs with nonatmos-blocked cardinal turfs AND -// diagonal turfs that can share atmos with *both* of the cardinal turfs +///We populate a list of turfs with nonatmos-blocked cardinal turfs AND +///diagonal turfs that can share atmos with *both* of the cardinal turfs /obj/machinery/atmospherics/components/unary/vent_scrubber/proc/check_turfs() adjacent_turfs.Cut() var/turf/T = get_turf(src) - if(istype(T)) - adjacent_turfs = T.GetAtmosAdjacentTurfs(alldir = 1) + adjacent_turfs = T.GetAtmosAdjacentTurfs(alldir = TRUE) /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")) return 0 + var/old_widenet = widenet + var/old_scrubbing = scrubbing + var/old_filter_length = length(filter_types) + var/atom/signal_sender = signal.data["user"] if("power" in signal.data) @@ -196,7 +183,6 @@ if("toggle_widenet" in signal.data) widenet = !widenet - var/old_scrubbing = scrubbing if("scrubbing" in signal.data) scrubbing = text2num(signal.data["scrubbing"]) if("toggle_scrubbing" in signal.data) @@ -221,8 +207,26 @@ return //do not update_icon broadcast_status() - update_icon() - return + update_appearance() + + 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() . = ..() diff --git a/code/modules/atmospherics/machinery/other/miner.dm b/code/modules/atmospherics/machinery/other/miner.dm index c025855411842..dae6b936525d0 100644 --- a/code/modules/atmospherics/machinery/other/miner.dm +++ b/code/modules/atmospherics/machinery/other/miner.dm @@ -89,15 +89,15 @@ var/P = G.return_pressure() switch(power_draw) if(GASMINER_POWER_NONE) - active_power_usage = 0 + update_use_power(ACTIVE_POWER_USE, 0) if(GASMINER_POWER_STATIC) - active_power_usage = power_draw_static + update_use_power(ACTIVE_POWER_USE, power_draw_static) 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) - 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) - active_power_usage = (spawn_mol * power_draw_dynamic_mol_coeff) + (P * power_draw_dynamic_kpa_coeff) + power_draw_static + 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) var/turf/T = get_turf(src) diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm index fdfd77d663e06..36cf305b8b096 100644 --- a/code/modules/atmospherics/machinery/portable/scrubber.dm +++ b/code/modules/atmospherics/machinery/portable/scrubber.dm @@ -53,7 +53,7 @@ return if(is_operational) if(prob(50 / severity)) - on = !on + on = FALSE //rip on = !on update_appearance() @@ -136,7 +136,7 @@ if((!anchored && !movable) || !is_operational) on = FALSE update_icon() - use_power = on ? ACTIVE_POWER_USE : IDLE_POWER_USE + update_use_power(on ? ACTIVE_POWER_USE : IDLE_POWER_USE) if(!on) return diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm index 1b5a23f470210..65c4ed57f0ca8 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm @@ -374,8 +374,10 @@ /obj/machinery/smartfridge/drying_rack/proc/toggle_drying(forceoff) if(drying || forceoff) drying = FALSE + update_use_power(IDLE_POWER_USE) else drying = TRUE + update_use_power(ACTIVE_POWER_USE) //how does it use power? just don't question it! update_appearance() /obj/machinery/smartfridge/drying_rack/proc/rack_dry(obj/item/target) diff --git a/code/modules/holodeck/computer.dm b/code/modules/holodeck/computer.dm index 80087ed81b470..615f249f12f31 100644 --- a/code/modules/holodeck/computer.dm +++ b/code/modules/holodeck/computer.dm @@ -215,7 +215,7 @@ GLOBAL_LIST_INIT(typecache_holodeck_linked_floorcheck_ok, typecacheof(list(/turf spawning_simulation = TRUE active = (map_id != offline_program) - use_power = active + IDLE_POWER_USE + update_use_power(active + IDLE_POWER_USE) program = map_id //clear the items from the previous program @@ -337,7 +337,7 @@ GLOBAL_LIST_INIT(typecache_holodeck_linked_floorcheck_ok, typecacheof(list(/turf derez(item) for(var/obj/effect/holodeck_effect/holo_effect as anything in effects) 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) if(active == toggleOn) diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 64f02071a6094..aee971d174441 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -6,6 +6,8 @@ pixel_z = 8 obj_flags = CAN_BE_HIT | UNIQUE_RENAME circuit = /obj/item/circuitboard/machine/hydroponics + idle_power_usage = 5000 + use_power = NO_POWER_USE var/waterlevel = 100 //The amount of water in the tray (max 100) var/maxwater = 100 //The maximum amount of water in the tray var/nutrilevel = 10 //The amount of nutrient in the tray (max 10) @@ -101,12 +103,23 @@ else return ..() +/obj/machinery/hydroponics/power_change() + . = ..() + if(machine_stat & NOPOWER && self_sustaining) + self_sustaining = FALSE + /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 if(myseed && (myseed.loc != src)) myseed.forceMove(src) + if(!powered() && self_sustaining) + visible_message("[name]'s auto-grow functionality shuts off!") + update_use_power(NO_POWER_USE) + self_sustaining = FALSE + update_appearance() + if(self_sustaining) adjustNutri(0.5 * delta_time) adjustWater(rand(1,2) * delta_time * 0.5) diff --git a/code/modules/power/apc/apc_main.dm b/code/modules/power/apc/apc_main.dm index cada253c82ce5..c61cc505e6884 100644 --- a/code/modules/power/apc/apc_main.dm +++ b/code/modules/power/apc/apc_main.dm @@ -58,7 +58,7 @@ ///State of the apc charging (not charging, charging, fully charged) var/charging = APC_NOT_CHARGING ///Can the APC charge? - var/chargemode = 1 + var/chargemode = TRUE ///Number of ticks where the apc is trying to recharge var/chargecount = 0 ///Is the apc interface locked? @@ -459,6 +459,7 @@ force_update = TRUE return +//dont use any power from that channel if we shut that power channel off lastused_light = APC_CHANNEL_IS_ON(lighting) ? area.power_usage[AREA_USAGE_LIGHT] + area.power_usage[AREA_USAGE_STATIC_LIGHT] : 0 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 diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index 3efa5dc72c48b..38d0aabdc37c8 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -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) charging_state = POWER_IDLE 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. var/alert = FALSE if(SSticker.IsRoundInProgress()) diff --git a/code/modules/power/monitor.dm b/code/modules/power/monitor.dm index 03c38fc907753..4b13381deb8c7 100644 --- a/code/modules/power/monitor.dm +++ b/code/modules/power/monitor.dm @@ -41,10 +41,10 @@ /obj/machinery/computer/monitor/process() if(!get_powernet()) - use_power = IDLE_POWER_USE + update_use_power(IDLE_POWER_USE) search() else - use_power = ACTIVE_POWER_USE + update_use_power(ACTIVE_POWER_USE) record() /obj/machinery/computer/monitor/proc/search() //keep in sync with /datum/computer_file/program/power_monitor's version diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index 0a3799447ca66..289c65a980541 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -73,7 +73,7 @@ // returns true if the area has power on given channel (or doesn't require power). // defaults to power_channel -/obj/machinery/proc/powered(var/chan = -1) // defaults to power_channel +/obj/machinery/proc/powered(chan = power_channel) if(!use_power) return TRUE if(!loc) @@ -83,24 +83,69 @@ var/area/A = get_area(src) // make sure it's in an area if(!A) return FALSE // if not, then not powered - if(chan == -1) - chan = power_channel return A.powered(chan) // return power status of the area // increment the power usage stats for an area -/obj/machinery/proc/use_power(amount, chan = -1) // defaults to power_channel - var/area/A = get_area(src) // make sure it's in an area +/obj/machinery/proc/use_power(amount, chan = power_channel) + var/area/A = get_area(src) // make sure it's in an area + 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. + * - Amount: How much power the APC's cell is to be costed. + */ +/obj/machinery/proc/directly_use_power(amount) + var/area/A = get_area(src) + var/obj/machinery/power/apc/local_apc if(!A) - return - if(chan == -1) - chan = power_channel - A.use_power(amount, chan) + return FALSE + local_apc = A.apc + if(!local_apc) + return FALSE + if(!local_apc.cell) + return FALSE + local_apc.cell.use(amount) + return TRUE + +/** + * Attempts to draw power directly from the APC's Powernet rather than the APC's battery. For high-draw machines, like the cell charger + * + * Checks the surplus power on the APC's powernet, and compares to the requested amount. If the requested amount is available, this proc + * will add the amount to the APC's usage and return that amount. Otherwise, this proc will return FALSE. + * If the take_any var arg is set to true, this proc will use and return any surplus that is under the requested amount, assuming that + * the surplus is above zero. + * Args: + * - amount, the amount of power requested from the Powernet. In standard loosely-defined SS13 power units. + * - take_any, a bool of whether any amount of power is acceptable, instead of all or nothing. Defaults to FALSE + */ +/obj/machinery/proc/use_power_from_net(amount, take_any = FALSE) + if(amount <= 0) //just in case + return FALSE + var/area/home = get_area(src) + + if(!home) + return FALSE //apparently space isn't an area + if(!home.requires_power) + return amount //Non-power eaters get free power, don't ask why + if(!home.always_unpowered) + return amount //Ruins get free power, don't ask why + + var/obj/machinery/power/apc/local_apc = home.apc + if(!local_apc) + return FALSE + var/surplus = local_apc.surplus() + if(surplus <= 0) //I don't know if powernet surplus can ever end up negative, but I'm just gonna failsafe it + return FALSE + if(surplus < amount) + if(!take_any) + return FALSE + amount = surplus + local_apc.add_load(amount) + return amount /obj/machinery/proc/addStaticPower(value, powerchannel) var/area/A = get_area(src) - if(!A) - return - A.addStaticPower(value, powerchannel) + A?.addStaticPower(value, powerchannel) /obj/machinery/proc/removeStaticPower(value, powerchannel) addStaticPower(-value, powerchannel) diff --git a/code/modules/power/powernet.dm b/code/modules/power/powernet.dm index 1a6a725e4e76b..295d340db0a7c 100644 --- a/code/modules/power/powernet.dm +++ b/code/modules/power/powernet.dm @@ -80,7 +80,7 @@ //see if there's a surplus of power remaining in the powernet and stores unused power in the SMES netexcess = avail - load - if(netexcess > 100 && nodes && nodes.len) // if there was excess power last cycle + if(netexcess > 100 && nodes && length(nodes)) // if there was excess power last cycle 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 diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 6bef2d1f561e4..1ad129982a0b7 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -99,7 +99,7 @@ fire_delay = fire_shoot_delay for(var/obj/item/stock_parts/manipulator/manipulator in component_parts) 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) . = ..() @@ -534,9 +534,9 @@ /obj/machinery/power/emitter/ctf name = "Energy Cannon" active = TRUE - active_power_usage = FALSE - idle_power_usage = FALSE + active_power_usage = 0 + idle_power_usage = 0 locked = TRUE req_access_txt = "100" welded = TRUE - use_power = FALSE + use_power = NO_POWER_USE diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm index 604528e2c7de5..1830bd1a64ad3 100644 --- a/code/modules/reagents/chemistry/machinery/pandemic.dm +++ b/code/modules/reagents/chemistry/machinery/pandemic.dm @@ -7,7 +7,7 @@ density = TRUE icon = 'icons/obj/chemical.dmi' icon_state = "pand0" - use_power = TRUE + use_power = IDLE_POWER_USE idle_power_usage = 20 resistance_flags = ACID_PROOF circuit = /obj/item/circuitboard/computer/pandemic diff --git a/code/modules/station_goals/shield.dm b/code/modules/station_goals/shield.dm index c1a85eb9bde21..c8d987987bd5d 100644 --- a/code/modules/station_goals/shield.dm +++ b/code/modules/station_goals/shield.dm @@ -89,7 +89,7 @@ icon_state = "sat_inactive" anchored = FALSE density = TRUE - use_power = FALSE + use_power = NO_POWER_USE var/mode = "NTPROBEV0.8" var/active = FALSE var/static/gid = 0 diff --git a/tgui/packages/tgui/interfaces/AirAlarm.js b/tgui/packages/tgui/interfaces/AirAlarm.js index b8d2550f862b4..75aa1e0301d9a 100644 --- a/tgui/packages/tgui/interfaces/AirAlarm.js +++ b/tgui/packages/tgui/interfaces/AirAlarm.js @@ -206,10 +206,10 @@ const AirAlarmControlThresholds = (props, context) => { - min2 - min1 - max1 - max2 + hazard_min + warning_min + warning_max + hazard_max From 6401fa75903fe664d90c1914942a5c63a336d47d Mon Sep 17 00:00:00 2001 From: PigeonVerde322 Date: Sun, 14 Jul 2024 15:36:22 +0200 Subject: [PATCH 02/12] 515 preparation moment --- code/game/machinery/_machinery.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 46891315dafb2..560d39d17eb31 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -204,9 +204,9 @@ 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) + RegisterSignal(our_area, COMSIG_AREA_POWER_CHANGE, PROC_REF(power_change)) + RegisterSignal(src, COMSIG_ENTER_AREA, PROC_REF(on_enter_area)) + RegisterSignal(src, COMSIG_EXIT_AREA, PROC_REF(on_exit_area)) /** * proc to call when the machine stops requiring power after a duration of requiring power From 4eb08d08a228bcdc921df8b61d70a3b371b96113 Mon Sep 17 00:00:00 2001 From: PigeonVerde322 Date: Sat, 20 Jul 2024 15:31:56 +0200 Subject: [PATCH 03/12] WHY GIT WHY --- .../atmospherics/machinery/airalarm.dm | 78 ------------------- 1 file changed, 78 deletions(-) diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 069f1d5363ea1..81ab59384f414 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -113,86 +113,8 @@ GAS_PLUOXIUM = new/datum/tlv(-1, -1, 5, 6), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires ) -<<<<<<< HEAD /obj/machinery/airalarm/New(mapload, ndir, nbuild) ..() -======= -/obj/machinery/airalarm/server // No checks here. - TLV = list( - "pressure" = new/datum/tlv/no_checks, - "temperature" = new/datum/tlv/no_checks, - GAS_O2 = new/datum/tlv/no_checks, - GAS_N2 = new/datum/tlv/no_checks, - GAS_CO2 = new/datum/tlv/no_checks, - GAS_PLASMA = new/datum/tlv/no_checks, - GAS_NITROUS = new/datum/tlv/no_checks, - GAS_BZ = new/datum/tlv/no_checks, - GAS_HYPERNOB = new/datum/tlv/no_checks, - GAS_H2O = new/datum/tlv/no_checks, - GAS_TRITIUM = new/datum/tlv/no_checks, - GAS_STIMULUM = new/datum/tlv/no_checks, - GAS_NITRYL = new/datum/tlv/no_checks, - GAS_PLUOXIUM = new/datum/tlv/no_checks - ) - -/obj/machinery/airalarm/kitchen_cold_room // Kitchen cold rooms start off at -20°C or 253.15 K. - 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(T0C-273.15, T0C-80, T0C-10, T0C+10), - GAS_O2 = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa - GAS_N2 = new/datum/tlv(-1, -1, 1000, 1000), - GAS_CO2 = new/datum/tlv(-1, -1, 5, 10), - GAS_PLASMA = new/datum/tlv/dangerous, - GAS_NITROUS = new/datum/tlv/dangerous, - GAS_BZ = new/datum/tlv/dangerous, - GAS_HYPERNOB = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic - GAS_H2O = new/datum/tlv/dangerous, - GAS_TRITIUM = new/datum/tlv/dangerous, - GAS_STIMULUM = new/datum/tlv/dangerous, - GAS_NITRYL = new/datum/tlv/dangerous, - GAS_PLUOXIUM = new/datum/tlv(-1, -1, 1000, 1000) // Unlike oxygen, pluoxium does not fuel plasma/tritium fires - ) - -/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_TOX, ACCESS_TOX_STORAGE) - -/obj/machinery/airalarm/all_access - name = "all-access air alarm" - desc = "This particular atmospherics 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) - -MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/airalarm, 24) - -//all air alarms in area are connected via magic -/area - var/list/air_vent_names = list() - var/list/air_scrub_names = list() - var/list/air_vent_info = list() - var/list/air_scrub_info = list() - -/obj/machinery/airalarm/Initialize(mapload, ndir, nbuild) - . = ..() ->>>>>>> a3b142770114888d37337d81fade833b83798ffd wires = new /datum/wires/airalarm(src) if(ndir) setDir(ndir) From e4e4fb7196a005f08c021c90a4a435024832b5cb Mon Sep 17 00:00:00 2001 From: PigeonVerde322 Date: Wed, 7 Aug 2024 19:38:50 +0200 Subject: [PATCH 04/12] Machinery will now tell if it's unpowered on examine --- code/game/machinery/_machinery.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 87a11dc5f6e06..eadc3d7af7e7a 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -901,6 +901,8 @@ . += display_parts(user, TRUE) if(return_blood_DNA()) . += "It's smeared with blood!" + if(!is_operational && (machine_stat & (NOPOWER))) + . += "It's currently unpowered!" //called on machinery construction (i.e from frame to machinery) but not on initialization /obj/machinery/proc/on_construction() From ae4ef560a65d47ec7fb7f2fa93c6b531fe745d22 Mon Sep 17 00:00:00 2001 From: PigeonVerde322 Date: Tue, 27 Aug 2024 14:13:40 +0200 Subject: [PATCH 05/12] whoops --- code/game/atoms_movable.dm | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 970148dea4320..0b5be56586805 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1226,23 +1226,6 @@ for(var/atom/movable/location as anything in nested_locs) LAZYREMOVEASSOC(location.important_recursive_contents, channel, gone.important_recursive_contents[channel]) -///allows this movable to know when it has "entered" another area no matter how many movable atoms its stuffed into, uses important_recursive_contents -/atom/movable/proc/become_area_sensitive(trait_source = TRAIT_GENERIC) - if(!HAS_TRAIT(src, TRAIT_AREA_SENSITIVE)) - for(var/atom/movable/location as anything in get_nested_locs(src) + src) - LAZYADDASSOCLIST(location.important_recursive_contents, RECURSIVE_CONTENTS_AREA_SENSITIVE, src) - ADD_TRAIT(src, TRAIT_AREA_SENSITIVE, trait_source) -///removes the area sensitive channel from the important_recursive_contents list of this and all nested locs containing us if there are no more source of the trait left -/atom/movable/proc/lose_area_sensitivity(trait_source = TRAIT_GENERIC) - if(!HAS_TRAIT(src, TRAIT_AREA_SENSITIVE)) - return - REMOVE_TRAIT(src, TRAIT_AREA_SENSITIVE, trait_source) - if(HAS_TRAIT(src, TRAIT_AREA_SENSITIVE)) - return - - for(var/atom/movable/location as anything in get_nested_locs(src) + src) - LAZYREMOVEASSOC(location.important_recursive_contents, RECURSIVE_CONTENTS_AREA_SENSITIVE, src) - ///allows this movable to hear and adds itself to the important_recursive_contents list of itself and every movable loc its in /atom/movable/proc/become_hearing_sensitive(trait_source = TRAIT_GENERIC) if(!HAS_TRAIT(src, TRAIT_HEARING_SENSITIVE)) From 881875cf42ab8cd80af1f73babe1e0a966004f1f Mon Sep 17 00:00:00 2001 From: PigeonVerde322 Date: Tue, 27 Aug 2024 14:17:09 +0200 Subject: [PATCH 06/12] redefined merge moment --- code/__DEFINES/traits.dm | 8 -------- 1 file changed, 8 deletions(-) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 3e763373b0adc..d207836b91066 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -299,14 +299,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai ///every hearing sensitive atom has this trait #define TRAIT_HEARING_SENSITIVE "hearing_sensitive" -//important_recursive_contents traits -/* - * Used for movables that need to be updated, via COMSIG_ENTER_AREA and COMSIG_EXIT_AREA, when transitioning areas. - * Use [/atom/movable/proc/become_area_sensitive(trait_source)] to properly enable it. How you remove it isn't as important. - */ -#define TRAIT_AREA_SENSITIVE "area-sensitive" -///every hearing sensitive atom has this trait - // item traits #define TRAIT_NODROP "nodrop" #define TRAIT_NO_STORAGE_INSERT "no_storage_insert" //cannot be inserted in a storage. From 2144f3f8c08a2d44e318712f10f10a9a2841556d Mon Sep 17 00:00:00 2001 From: PigeonVerde322 Date: Sun, 8 Sep 2024 11:51:20 +0200 Subject: [PATCH 07/12] i'm lost --- code/modules/atmospherics/machinery/airalarm.dm | 3 ++- code/modules/power/power.dm | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 61725582c8420..e7c154656dc74 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -145,7 +145,6 @@ )) GLOB.zclear_atoms += src - /obj/machinery/airalarm/examine(mob/user) . = ..() switch(buildstage) @@ -879,6 +878,8 @@ /obj/machinery/airalarm/away //general away mission access req_access = list(ACCESS_AWAY_GENERAL) +CREATION_TEST_IGNORE_SUBTYPES(/obj/machinery/airalarm) + MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/airalarm, 24) /**end of air alarms variants **/ diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index 7679a2f7b334a..0b6c73ab73070 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -300,9 +300,6 @@ . += C return . - - - //remove the old powernet and replace it with a new one throughout the network. /proc/propagate_network(obj/O, datum/powernet/PN) var/list/worklist = list() From 4558873be351a85589a95509a07a954c5fc0e2ae Mon Sep 17 00:00:00 2001 From: PigeonVerde322 Date: Tue, 24 Dec 2024 09:24:00 +0100 Subject: [PATCH 08/12] finally out of the hell air alarms still broken --- code/modules/atmospherics/machinery/airalarm.dm | 7 ------- 1 file changed, 7 deletions(-) diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 872e2700da550..15a98e1b16f81 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -186,13 +186,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/airalarm, 24) -//all air alarms in area are connected via magic -/area - var/list/air_vent_names = list() - var/list/air_scrub_names = list() - var/list/air_vent_info = list() - var/list/air_scrub_info = list() - CREATION_TEST_IGNORE_SUBTYPES(/obj/machinery/airalarm) /obj/machinery/airalarm/Initialize(mapload, ndir, nbuild) From f53f894c9f0d1ea408f6e07affbfcee7fd53807e Mon Sep 17 00:00:00 2001 From: PigeonVerde322 Date: Tue, 24 Dec 2024 11:21:11 +0100 Subject: [PATCH 09/12] Lost once again --- .../atmospherics/machinery/airalarm.dm | 77 ++++++------------- 1 file changed, 22 insertions(+), 55 deletions(-) diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 15a98e1b16f81..b75de7346aa83 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -1,14 +1,16 @@ + +// A datum for dealing with threshold limit values /datum/tlv var/warning_min var/warning_max var/hazard_min var/hazard_max -/datum/tlv/New(min2 as num, min1 as num, max1 as num, max2 as num) - if(min2) - hazard_min = min2 +/datum/tlv/New(min1 as num, min2 as num, max1 as num, max2 as num) if(min1) warning_min = min1 + if(min2) + hazard_min = min2 if(max1) warning_max = max1 if(max2) @@ -94,7 +96,7 @@ ///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/static/list/atmos_connections = list(COMSIG_TURF_EXPOSE = PROC_REF(check_air_dangerlevel)) + var/static/list/atmos_connections = list(COMSIG_TURF_EXPOSE = PROC_REF(check_air_dangerlevel)) //STOP NAGGING ME 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 hazard_min, warning_min, warning_max, hazard_max @@ -113,13 +115,6 @@ GAS_PLUOXIUM = new/datum/tlv(-1, -1, 5, 6), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires ) - -/datum/armor/machinery_airalarm - energy = 100 - rad = 100 - fire = 90 - acid = 30 - /obj/machinery/airalarm/server // No checks here. TLV = list( "pressure" = new/datum/tlv/no_checks, @@ -156,48 +151,15 @@ GAS_PLUOXIUM = new/datum/tlv(-1, -1, 1000, 1000) // Unlike oxygen, pluoxium does not fuel plasma/tritium fires ) -/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_TOX, ACCESS_TOX_STORAGE) - -/obj/machinery/airalarm/all_access - name = "all-access air alarm" - desc = "This particular atmospherics 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) - -MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/airalarm, 24) - -CREATION_TEST_IGNORE_SUBTYPES(/obj/machinery/airalarm) - /obj/machinery/airalarm/Initialize(mapload, ndir, nbuild) . = ..() wires = new /datum/wires/airalarm(src) + if(ndir) setDir(ndir) - if(nbuild) buildstage = 0 panel_open = TRUE - if(name == initial(name)) name = "[get_area_name(src)] Air Alarm" @@ -454,10 +416,10 @@ CREATION_TEST_IGNORE_SUBTYPES(/obj/machinery/airalarm) /obj/machinery/airalarm/proc/shock(mob/user, prb) - if((machine_stat & (NOPOWER))) // unpowered, no shock + if((machine_stat & (NOPOWER)))/// Unpowered, no shock return TRUE if(!prob(prb)) - return FALSE //you lucked out, no shock for you + return FALSE ///You don't get shocked today... altought when was the last time soneone got shocked by a fire alarm? var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread s.set_up(5, 1, src) s.start() //sparks always. @@ -673,31 +635,30 @@ CREATION_TEST_IGNORE_SUBTYPES(/obj/machinery/airalarm) /** * 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) return var/datum/tlv/current_tlv - //cache for REALLY fast speed (lists are references anyways) + ///Cache for REALLY fast speed (lists are references anyways), some atmos systems just gotta go fast. var/list/cached_tlv = TLV - var/datum/tlv/cur_tlv - + var/list/env_gases = environment.get_gases() var/partial_pressure = R_IDEAL_GAS_EQUATION * exposed_temperature / environment.return_volume() current_tlv = cached_tlv["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) current_tlv = cached_tlv["temperature"] var/temperature_dangerlevel = current_tlv.get_danger_level(exposed_temperature) var/gas_dangerlevel = 0 - for(var/gas_id in environment.get_gases()) - if(!(gas_id in cached_tlv)) // We're not interested in this gas, it seems. + for(var/gas_id in env_gases) + if(!(gas_id in cached_tlv)) /// We're not interested in this gas, it seems. continue current_tlv = cached_tlv[gas_id] gas_dangerlevel = max(gas_dangerlevel, current_tlv.get_danger_level(environment.get_moles(gas_id) * partial_pressure)) @@ -887,6 +848,12 @@ CREATION_TEST_IGNORE_SUBTYPES(/obj/machinery/airalarm) new /obj/item/stack/cable_coil(loc, 3) qdel(src) +/datum/armor/machinery_airalarm + energy = 100 + rad = 100 + fire = 90 + acid = 30 + /**ALL OF THAT AIR ALARMS VARIATIONS RIGHT HERE :CLAP:*/ /obj/machinery/airalarm/server // No checks here. @@ -1030,8 +997,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/airalarm, 24) return var/datum/tlv/settings = connected_alarm.TLV[options_map[current_option]] - settings.hazard_min = min_2 settings.warning_min = min_1 + settings.hazard_min = min_2 settings.warning_max = max_1 settings.hazard_max = max_2 From f8b0f300afa1d04090584db0bf5c7c2ae99c28e3 Mon Sep 17 00:00:00 2001 From: PigeonVerde322 Date: Tue, 24 Dec 2024 19:34:32 +0100 Subject: [PATCH 10/12] no more endless power from solars --- code/game/area/Space_Station_13_areas.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/game/area/Space_Station_13_areas.dm b/code/game/area/Space_Station_13_areas.dm index 39db3eb4bdb85..865e96087e51d 100644 --- a/code/game/area/Space_Station_13_areas.dm +++ b/code/game/area/Space_Station_13_areas.dm @@ -963,7 +963,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station //Solars /area/solar - requires_power = FALSE + //requires_power = FALSE /* YOU WISH FOR INFINITE POWER YOU STINGY CHEAPO, TOO BAD */ dynamic_lighting = DYNAMIC_LIGHTING_IFSTARLIGHT area_flags = UNIQUE_AREA flags_1 = NONE @@ -1011,8 +1011,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "Port Bow Solar Array" icon_state = "panelsFP" - - //Solar Maint /area/maintenance/solars From 1e8d2dda3a57e1d948fe1218da9187c14f532327 Mon Sep 17 00:00:00 2001 From: PigeonVerde322 Date: Wed, 25 Dec 2024 01:03:16 +0100 Subject: [PATCH 11/12] fix? --- code/game/area/Space_Station_13_areas.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/area/Space_Station_13_areas.dm b/code/game/area/Space_Station_13_areas.dm index 29d5a11124257..39e63ba4c5de0 100644 --- a/code/game/area/Space_Station_13_areas.dm +++ b/code/game/area/Space_Station_13_areas.dm @@ -966,6 +966,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/solar //requires_power = FALSE /* YOU WISH FOR INFINITE POWER YOU STINGY CHEAPO, TOO BAD */ + always_unpowered = TRUE dynamic_lighting = DYNAMIC_LIGHTING_IFSTARLIGHT area_flags = UNIQUE_AREA | NO_GRAVITY flags_1 = NONE From 3dca7a6b3661e99d7313d46b5425ba36220f605a Mon Sep 17 00:00:00 2001 From: PigeonVerde322 Date: Wed, 25 Dec 2024 01:30:20 +0100 Subject: [PATCH 12/12] eee --- .../atmospherics/machinery/airalarm.dm | 113 +++++++----------- 1 file changed, 40 insertions(+), 73 deletions(-) diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index b75de7346aa83..8738bd95edcc8 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -115,66 +115,25 @@ GAS_PLUOXIUM = new/datum/tlv(-1, -1, 5, 6), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires ) -/obj/machinery/airalarm/server // No checks here. - TLV = list( - "pressure" = new/datum/tlv/no_checks, - "temperature" = new/datum/tlv/no_checks, - GAS_O2 = new/datum/tlv/no_checks, - GAS_N2 = new/datum/tlv/no_checks, - GAS_CO2 = new/datum/tlv/no_checks, - GAS_PLASMA = new/datum/tlv/no_checks, - GAS_NITROUS = new/datum/tlv/no_checks, - GAS_BZ = new/datum/tlv/no_checks, - GAS_HYPERNOB = new/datum/tlv/no_checks, - GAS_H2O = new/datum/tlv/no_checks, - GAS_TRITIUM = new/datum/tlv/no_checks, - GAS_STIMULUM = new/datum/tlv/no_checks, - GAS_NITRYL = new/datum/tlv/no_checks, - GAS_PLUOXIUM = new/datum/tlv/no_checks - ) - -/obj/machinery/airalarm/kitchen_cold_room // Kitchen cold rooms start off at -20°C or 253.15 K. - 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(T0C-273.15, T0C-80, T0C-10, T0C+10), - GAS_O2 = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa - GAS_N2 = new/datum/tlv(-1, -1, 1000, 1000), - GAS_CO2 = new/datum/tlv(-1, -1, 5, 10), - GAS_PLASMA = new/datum/tlv/dangerous, - GAS_NITROUS = new/datum/tlv/dangerous, - GAS_BZ = new/datum/tlv/dangerous, - GAS_HYPERNOB = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic - GAS_H2O = new/datum/tlv/dangerous, - GAS_TRITIUM = new/datum/tlv/dangerous, - GAS_STIMULUM = new/datum/tlv/dangerous, - GAS_NITRYL = new/datum/tlv/dangerous, - GAS_PLUOXIUM = new/datum/tlv(-1, -1, 1000, 1000) // Unlike oxygen, pluoxium does not fuel plasma/tritium fires - ) /obj/machinery/airalarm/Initialize(mapload, ndir, nbuild) . = ..() wires = new /datum/wires/airalarm(src) - if(ndir) setDir(ndir) + if(nbuild) buildstage = 0 panel_open = TRUE + pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) + pixel_y = (dir & 3)? (dir == 1 ? -24 : 24) : 0 + if(name == initial(name)) name = "[get_area_name(src)] Air Alarm" alarm_manager = new(src) update_appearance() -/obj/machinery/airalarm/Destroy() - SSradio.remove_object(src, frequency) - QDEL_NULL(wires) - QDEL_NULL(alarm_manager) - GLOB.zclear_atoms -= src - return ..() - -/obj/machinery/airalarm/Initialize(mapload) - . = ..() set_frequency(frequency) AddElement(/datum/element/connect_loc, atmos_connections) AddComponent(/datum/component/usb_port, list( @@ -182,6 +141,14 @@ )) GLOB.zclear_atoms += src + +/obj/machinery/airalarm/Destroy() + SSradio.remove_object(src, frequency) + QDEL_NULL(wires) + QDEL_NULL(alarm_manager) + GLOB.zclear_atoms -= src + return ..() + /obj/machinery/airalarm/examine(mob/user) . = ..() switch(buildstage) @@ -858,38 +825,38 @@ /obj/machinery/airalarm/server // No checks here. TLV = list( - "pressure" = new/datum/tlv/no_checks, - "temperature" = new/datum/tlv/no_checks, - GAS_O2 = new/datum/tlv/no_checks, - GAS_N2 = new/datum/tlv/no_checks, - GAS_CO2 = new/datum/tlv/no_checks, - GAS_PLASMA = new/datum/tlv/no_checks, - GAS_NITROUS = new/datum/tlv/no_checks, - GAS_BZ = new/datum/tlv/no_checks, - GAS_HYPERNOB = new/datum/tlv/no_checks, - GAS_H2O = new/datum/tlv/no_checks, - GAS_TRITIUM = new/datum/tlv/no_checks, - GAS_STIMULUM = new/datum/tlv/no_checks, - GAS_NITRYL = new/datum/tlv/no_checks, - GAS_PLUOXIUM = new/datum/tlv/no_checks + "pressure" = new/datum/tlv/no_checks, + "temperature" = new/datum/tlv/no_checks, + GAS_O2 = new/datum/tlv/no_checks, + GAS_N2 = new/datum/tlv/no_checks, + GAS_CO2 = new/datum/tlv/no_checks, + GAS_PLASMA = new/datum/tlv/no_checks, + GAS_NITROUS = new/datum/tlv/no_checks, + GAS_BZ = new/datum/tlv/no_checks, + GAS_HYPERNOB = new/datum/tlv/no_checks, + GAS_H2O = new/datum/tlv/no_checks, + GAS_TRITIUM = new/datum/tlv/no_checks, + GAS_STIMULUM = new/datum/tlv/no_checks, + GAS_NITRYL = new/datum/tlv/no_checks, + GAS_PLUOXIUM = new/datum/tlv/no_checks ) /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/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 + "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), + GAS_O2 = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa + GAS_N2 = new/datum/tlv(-1, -1, 1000, 1000), + GAS_CO2 = new/datum/tlv(-1, -1, 5, 10), + GAS_PLASMA = new/datum/tlv/dangerous, + GAS_NITROUS = new/datum/tlv/dangerous, + GAS_BZ = new/datum/tlv/dangerous, + GAS_HYPERNOB = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic + GAS_H2O = new/datum/tlv/dangerous, + GAS_TRITIUM = new/datum/tlv/dangerous, + GAS_STIMULUM = new/datum/tlv/dangerous, + GAS_NITRYL = new/datum/tlv/dangerous, + GAS_PLUOXIUM = new/datum/tlv(-1, -1, 1000, 1000), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires ) /obj/machinery/airalarm/unlocked