Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RECOUP/PORT] large refactor of machine/power code to cut down on processing time and wasted lists + Fixes age-old apc exploit #11188

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions beestation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
18 changes: 18 additions & 0 deletions code/__DEFINES/atmospherics/atmos_machinery.dm
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions code/__DEFINES/dcs/signals/signals_area.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
2 changes: 2 additions & 0 deletions code/__DEFINES/important_recursive_contents.dm
Original file line number Diff line number Diff line change
@@ -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"
8 changes: 6 additions & 2 deletions code/__DEFINES/machines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,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.
Expand Down
34 changes: 15 additions & 19 deletions code/controllers/subsystem/machines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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

Expand Down
31 changes: 24 additions & 7 deletions code/game/area/areas.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
*
Expand All @@ -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
Expand Down
6 changes: 4 additions & 2 deletions code/game/atoms.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions code/game/atoms_movable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
4 changes: 2 additions & 2 deletions code/game/machinery/Beacon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Loading
Loading