From 0be337d01c8f381a249d8678cc8cac5ce6bc1b96 Mon Sep 17 00:00:00 2001
From: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Date: Thu, 1 Oct 2020 13:19:52 -0700
Subject: [PATCH] Makes some things that rely on atmos adjacency more
sane/faster. (#54096)
* Replaces some CANATMOSPASS calls with a new define that checks if the turfs are in each others atmos adjacent list, as that's the same info that they want.
---
code/__DEFINES/atmospherics.dm | 6 ++++++
code/__HELPERS/areas.dm | 2 +-
code/datums/diseases/_disease.dm | 2 +-
code/game/objects/effects/glowshroom.dm | 6 +++++-
code/game/objects/effects/portals.dm | 6 ++++--
code/game/objects/items/RCD.dm | 2 +-
code/game/objects/items/melee/misc.dm | 1 -
code/modules/atmospherics/environmental/LINDA_system.dm | 1 +
code/modules/flufftext/Hallucination.dm | 2 +-
9 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm
index 7306d8e5ea4..9e104930f7a 100644
--- a/code/__DEFINES/atmospherics.dm
+++ b/code/__DEFINES/atmospherics.dm
@@ -240,6 +240,7 @@
/// just check density
#define ATMOS_PASS_DENSITY -2
+//DO NOT USE THESE FOR ACCESSING ATMOS DATA, THEY MUTATE THINGS WHEN CALLED. I WILL BEAT YOU WITH A STICK. See the actual proc for more details
#define CANATMOSPASS(A, O) ( A.CanAtmosPass == ATMOS_PASS_PROC ? A.CanAtmosPass(O) : ( A.CanAtmosPass == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPass ) )
#define CANVERTICALATMOSPASS(A, O) ( A.CanAtmosPassVertical == ATMOS_PASS_PROC ? A.CanAtmosPass(O, TRUE) : ( A.CanAtmosPassVertical == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPassVertical ) )
@@ -483,6 +484,11 @@ GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0))
#define CALCULATE_ADJACENT_TURFS(T) SSadjacent_air.queue[T] = 1
#endif
+//If you're doing spreading things related to atmos, DO NOT USE CANATMOSPASS, IT IS NOT CHEAP. use this instead, the info is cached after all. it's tweaked just a bit to allow for circular checks
+#define TURFS_CAN_SHARE(T1, T2) ((T2.atmos_adjacent_turfs[T1]) || LAZYLEN(T1.atmos_adjacent_turfs & T2.atmos_adjacent_turfs))
+//Use this to see if a turf is fully blocked or not, think windows or firelocks. Fails with 1x1 non full tile windows, but it's not worth the cost.
+#define TURF_SHARES(T) (LAZYLEN(T.atmos_adjacent_turfs))
+
GLOBAL_LIST_INIT(pipe_paint_colors, sortList(list(
"amethyst" = rgb(130,43,255), //supplymain
"blue" = rgb(0,0,255),
diff --git a/code/__HELPERS/areas.dm b/code/__HELPERS/areas.dm
index 34e00c7af22..5f9dd8b4e14 100644
--- a/code/__HELPERS/areas.dm
+++ b/code/__HELPERS/areas.dm
@@ -36,7 +36,7 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/engine/eng
if(break_if_found[checkT.type] || break_if_found[checkT.loc.type])
return FALSE
var/static/list/cardinal_cache = list("[NORTH]"=TRUE, "[EAST]"=TRUE, "[SOUTH]"=TRUE, "[WEST]"=TRUE)
- if(!cardinal_cache["[dir]"] || checkT.blocks_air || !CANATMOSPASS(sourceT, checkT))
+ if(!cardinal_cache["[dir]"] || !TURFS_CAN_SHARE(sourceT, checkT))
continue
found_turfs += checkT // Since checkT is connected, add it to the list to be processed
diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm
index 11981d15448..b5ea2211310 100644
--- a/code/datums/diseases/_disease.dm
+++ b/code/datums/diseases/_disease.dm
@@ -123,7 +123,7 @@
if(end == start)
return TRUE
var/turf/Temp = get_step_towards(end, start)
- if(!CANATMOSPASS(end, Temp))
+ if(!TURFS_CAN_SHARE(end, Temp)) //Don't go through a wall
return FALSE
end = Temp
diff --git a/code/game/objects/effects/glowshroom.dm b/code/game/objects/effects/glowshroom.dm
index ff4ef2489c8..784aa6d932e 100644
--- a/code/game/objects/effects/glowshroom.dm
+++ b/code/game/objects/effects/glowshroom.dm
@@ -110,6 +110,10 @@
return
var/turf/ownturf = get_turf(src)
+ if(!TURF_SHARES(ownturf)) //If we are in a 1x1 room
+ addtimer(CALLBACK(src, .proc/Spread), delay_spread, TIMER_UNIQUE|TIMER_NO_HASH_WAIT)
+ return //Deal with it not now
+
var/shrooms_planted = 0
var/list/possibleLocs = list()
//Lets collect a list of possible viewable turfs BEFORE we iterate for yield so we don't call view multiple
@@ -118,7 +122,7 @@
for(var/turf/open/floor/earth in view(3,src))
if(is_type_in_typecache(earth, blacklisted_glowshroom_turfs))
continue
- if(!ownturf.CanAtmosPass(earth))
+ if(!TURF_SHARES(earth))
continue
possibleLocs += earth
diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm
index 0643363c6d9..f4593ffd209 100644
--- a/code/game/objects/effects/portals.dm
+++ b/code/game/objects/effects/portals.dm
@@ -125,12 +125,14 @@
/obj/effect/portal/proc/unlink_atmos()
if(istype(atmos_source))
- if(istype(atmos_destination) && !atmos_source.Adjacent(atmos_destination) && !CANATMOSPASS(atmos_destination, atmos_source))
+ if(istype(atmos_destination))
LAZYREMOVE(atmos_source.atmos_adjacent_turfs, atmos_destination)
+ atmos_source.ImmediateCalculateAdjacentTurfs() //Just in case they were next to each other
atmos_source = null
if(istype(atmos_destination))
- if(istype(atmos_source) && !atmos_destination.Adjacent(atmos_source) && !CANATMOSPASS(atmos_source, atmos_destination))
+ if(istype(atmos_source))
LAZYREMOVE(atmos_destination.atmos_adjacent_turfs, atmos_source)
+ atmos_destination.ImmediateCalculateAdjacentTurfs()
atmos_destination = null
/obj/effect/portal/Destroy()
diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm
index 285a93185e1..36af0fe8336 100644
--- a/code/game/objects/items/RCD.dm
+++ b/code/game/objects/items/RCD.dm
@@ -832,7 +832,7 @@ RLD
for(var/direction in GLOB.cardinals)
var/turf/C = get_step(W, direction)
var/list/dupes = checkdupes(C)
- if(start.CanAtmosPass(C) && !dupes.len)
+ if((isspaceturf(C) || TURF_SHARES(C)) && !dupes.len)
candidates += C
if(!candidates.len)
to_chat(user, "Valid target not found...")
diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm
index 1dc5d7fa1ff..32eef0611ce 100644
--- a/code/game/objects/items/melee/misc.dm
+++ b/code/game/objects/items/melee/misc.dm
@@ -524,7 +524,6 @@
T.visible_message("[T] smacks into [src] and rapidly flashes to ash.",\
"You hear a loud crack as you are washed with a wave of heat.")
shard.Consume()
- CALCULATE_ADJACENT_TURFS(T)
/obj/item/melee/supermatter_sword/add_blood_DNA(list/blood_dna)
return FALSE
diff --git a/code/modules/atmospherics/environmental/LINDA_system.dm b/code/modules/atmospherics/environmental/LINDA_system.dm
index 241acbee29d..3dabf693d7e 100644
--- a/code/modules/atmospherics/environmental/LINDA_system.dm
+++ b/code/modules/atmospherics/environmental/LINDA_system.dm
@@ -16,6 +16,7 @@
/turf/open/CanAtmosPass = ATMOS_PASS_PROC
/turf/open/CanAtmosPassVertical = ATMOS_PASS_PROC
+//Do NOT use this to see if 2 turfs are connected, it mutates state, and we cache that info anyhow. Use TURFS_CAN_SHARE or TURF_SHARES depending on your usecase
/turf/open/CanAtmosPass(turf/T, vertical = FALSE)
var/dir = vertical? get_dir_multiz(src, T) : get_dir(src, T)
var/opp = REVERSE_DIR(dir)
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 7599000a31d..40f0750cc53 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -204,7 +204,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
for(var/turf/FT in flood_turfs)
for(var/dir in GLOB.cardinals)
var/turf/T = get_step(FT, dir)
- if((T in flood_turfs) || !FT.CanAtmosPass(T))
+ if((T in flood_turfs) || !TURFS_CAN_SHARE(T, FT) || isspaceturf(T)) //If we've gottem already, or if they're not alright to spread with.
continue
var/obj/effect/plasma_image_holder/pih = new(T)
var/image/new_plasma = image(image_icon, pih, image_state, FLY_LAYER)