Use can_atmos_pass to reduce proc-calls in c_airblock()

- Add additional can_atmos_pass value ATMOS_PASS_PROC which indicates custom behavior requiring calling the CanZASPass proc.
  - The benefit being for the other three values we DON'T need to call CanZASPass at all!  We already know the behavior without the overhead of a proc call.
  - Obviously any atom with can_atmos_pass = ATMOS_PASS_PROC cannot now call ..() in CanZASPass() since the default behavior would be to (recursively) call CanZASPass()
  - This required re-numbering the constants, so I also fixed all code that assumed particular values for the constants.
- Switched all types which overrode CanZASPass with custom logic to be can_atmos_pass = ATMOS_PASS_PROC
- Changed /turf/c_airblock() to skip calling /atom/movable/c_airblock() for the three can_atmos_pass values that don't require calling the proc.
This commit is contained in:
Leshana
2020-04-20 13:37:51 -04:00
parent 5c752e79f4
commit 10b0323d6f
9 changed files with 34 additions and 17 deletions

View File

@@ -16,11 +16,19 @@
// Inputs: The turf the airflow is from, which may not be the same as loc. is_zone is for conditionally disallowing merging.
// Outputs: Boolean if airflow can pass.
/atom/proc/CanZASPass(turf/T, is_zone)
// Behaviors defined here so when people directly call c_airblock it will still obey can_atmos_pass
switch(can_atmos_pass)
if(ATMOS_PASS_YES)
return TRUE
if(ATMOS_PASS_NO)
return FALSE
if(ATMOS_PASS_DENSITY)
return !density
if(ATMOS_PASS_PROC)
// Cowardly refuse to recursively self-call CanZASPass. The hero BYOND needs?
CRASH("can_atmos_pass = ATMOS_PASS_PROC but CanZASPass not overridden on [src] ([type])")
else
return can_atmos_pass
CRASH("Invalid can_atmos_pass = [can_atmos_pass] on [src] ([type])")
/turf/CanPass(atom/movable/mover, turf/target)
if(!target) return FALSE
@@ -87,6 +95,15 @@ turf/c_airblock(turf/other)
var/result = 0
for(var/mm in contents)
var/atom/movable/M = mm
result |= M.c_airblock(other)
switch(M.can_atmos_pass)
if(ATMOS_PASS_YES)
continue
if(ATMOS_PASS_NO)
return BLOCKED
if(ATMOS_PASS_DENSITY)
if(density)
return BLOCKED
if(ATMOS_PASS_PROC)
result |= M.c_airblock(other)
if(result == BLOCKED) return BLOCKED
return result

View File

@@ -4,3 +4,10 @@
#define BLOCKED 3 // Blocked, zone boundaries will not cross even if opened.
#define ZONE_MIN_SIZE 14 // Zones with less than this many turfs will always merge, even if the connection is not direct
// Used for quickly making certain things allow airflow or not.
// More complicated, conditional airflow should override CanZASPass().
#define ATMOS_PASS_YES 1 // Always blocks air and zones.
#define ATMOS_PASS_NO 2 // Never blocks air or zones.
#define ATMOS_PASS_DENSITY 3 // Blocks air and zones if density = 1, allows both if density = 0
#define ATMOS_PASS_PROC 4 // Call CanZASPass() using c_airblock

View File

@@ -94,9 +94,3 @@
#define ATMOSTANK_CO2 25000 // CO2 and PH are not critically important for station, only for toxins and alternative coolants, no need to store a lot of those.
#define ATMOSTANK_PHORON 25000
#define ATMOSTANK_NITROUSOXIDE 10000 // N2O doesn't have a real useful use, i guess it's on station just to allow refilling of sec's riot control canisters?
// Used for quickly making certain things allow airflow or not.
// More complicated, conditional airflow should override CanZASPass().
#define ATMOS_PASS_YES 1
#define ATMOS_PASS_NO 0
#define ATMOS_PASS_DENSITY -1 // Just checks density.

View File

@@ -9,7 +9,7 @@
anchored = 1
opacity = 1
density = 1
can_atmos_pass = ATMOS_PASS_DENSITY
can_atmos_pass = ATMOS_PASS_PROC
layer = DOOR_OPEN_LAYER
var/open_layer = DOOR_OPEN_LAYER
var/closed_layer = DOOR_CLOSED_LAYER
@@ -157,8 +157,8 @@
/obj/machinery/door/CanZASPass(turf/T, is_zone)
if(is_zone)
return !block_air_zones
return ..()
return !block_air_zones // Block merging unless block_air_zones = 0
return !density // Block airflow unless density = 0
/obj/machinery/door/proc/bumpopen(mob/user as mob)
if(operating) return

View File

@@ -14,6 +14,7 @@
opacity = 0
var/obj/item/weapon/airlock_electronics/electronics = null
explosion_resistance = 5
can_atmos_pass = ATMOS_PASS_PROC
air_properties_vary_with_direction = 1
/obj/machinery/door/window/New()
@@ -95,7 +96,7 @@
if(get_dir(T, loc) == turn(dir, 180))
if(is_zone) // No merging allowed.
return FALSE
return ..() // Air can flow if open (density == FALSE).
return !density // Air can flow if open (density == FALSE).
return TRUE // Windoors don't block if not facing the right way.
/obj/machinery/door/window/CheckExit(atom/movable/mover as mob|obj, turf/target as turf)

View File

@@ -7,6 +7,7 @@
anchored = 1
density = 0
opacity = 0
can_atmos_pass = ATMOS_PASS_PROC
/obj/effect/zone_divider/CanZASPass(turf/T, is_zone)
// Special case to prevent us from being part of a zone during the first air master tick.

View File

@@ -3,7 +3,7 @@
desc = "A window."
icon = 'icons/obj/structures_vr.dmi' // VOREStation Edit - New icons
density = 1
can_atmos_pass = ATMOS_PASS_DENSITY
can_atmos_pass = ATMOS_PASS_PROC
w_class = ITEMSIZE_NORMAL
layer = WINDOW_LAYER

View File

@@ -8,10 +8,6 @@
return !P.can_hit_target(src, P.permutated, src == P.original, TRUE)
return (!mover.density || !density || lying)
// There is no need to override this if you're just going to unconditionally return TRUE. Set can_atmos_pass instead.
///mob/CanZASPass(turf/T, is_zone)
// return TRUE
/mob/living/SelfMove(turf/n, direct)
// If on walk intent, don't willingly step into hazardous tiles.
// Unless the walker is confused.

View File

@@ -28,6 +28,7 @@
icon_state = "compressor"
anchored = TRUE
density = TRUE
can_atmos_pass = ATMOS_PASS_PROC
circuit = /obj/item/weapon/circuitboard/machine/power_compressor
var/obj/machinery/power/turbine/turbine
var/datum/gas_mixture/gas_contained