diff --git a/code/__DEFINES/turf_flags.dm b/code/__DEFINES/turf_flags.dm
index f71335e1f043..5ceb6f2e2ed8 100644
--- a/code/__DEFINES/turf_flags.dm
+++ b/code/__DEFINES/turf_flags.dm
@@ -1,4 +1,5 @@
#define CHANGETURF_DEFER_CHANGE 1
-#define CHANGETURF_IGNORE_AIR 2
+#define CHANGETURF_IGNORE_AIR 2 // This flag prevents changeturf from gathering air from nearby turfs to fill the new turf with an approximation of local air
#define CHANGETURF_FORCEOP 4
-#define CHANGETURF_SKIP 8 // A flag for PlaceOnTop to just instance the new turf instead of calling ChangeTurf. Used for uninitialized turfs NOTHING ELSE
\ No newline at end of file
+#define CHANGETURF_SKIP 8 // A flag for PlaceOnTop to just instance the new turf instead of calling ChangeTurf. Used for uninitialized turfs NOTHING ELSE
+#define CHANGETURF_INHERIT_AIR 16 // Inherit air from previous turf. Implies CHANGETURF_IGNORE_AIR
diff --git a/code/datums/components/storage/concrete/bag_of_holding.dm b/code/datums/components/storage/concrete/bag_of_holding.dm
index 0fd55c0ddd35..8a80434114ac 100644
--- a/code/datums/components/storage/concrete/bag_of_holding.dm
+++ b/code/datums/components/storage/concrete/bag_of_holding.dm
@@ -23,6 +23,8 @@
M.visible_message("The bluespace collapse crushes the air towards it, pulling [M] towards the ground...")
M.Knockdown(5, TRUE, TRUE) //Overrides stun absorbs.
T.TerraformTurf(/turf/open/chasm/magic, /turf/open/chasm/magic)
+ for (var/obj/structure/ladder/unbreakable/binary/ladder in GLOB.ladders)
+ ladder.ActivateAlmonds()
message_admins("[ADMIN_LOOKUPFLW(user)] detonated a bag of holding at [ADMIN_VERBOSEJMP(loccheck)].")
log_game("[key_name(user)] detonated a bag of holding at [AREACOORD(loccheck)].")
qdel(A)
diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm
index 139769e26976..d64ae75e2c66 100644
--- a/code/game/machinery/navbeacon.dm
+++ b/code/game/machinery/navbeacon.dm
@@ -37,10 +37,18 @@
GLOB.deliverybeacontags += location
/obj/machinery/navbeacon/Destroy()
- GLOB.navbeacons["[z]"] -= src //Remove from beacon list, if in one.
+ if (GLOB.navbeacons["[z]"])
+ GLOB.navbeacons["[z]"] -= src //Remove from beacon list, if in one.
GLOB.deliverybeacons -= src
return ..()
+/obj/machinery/navbeacon/onTransitZ(old_z, new_z)
+ if (GLOB.navbeacons["[old_z]"])
+ GLOB.navbeacons["[old_z]"] -= src
+ if (GLOB.navbeacons["[new_z]"])
+ GLOB.navbeacons["[new_z]"] += src
+ ..()
+
// set the transponder codes assoc list from codes_txt
/obj/machinery/navbeacon/proc/set_codes()
if(!codes_txt)
@@ -203,4 +211,4 @@ Transponder Codes:
"}
codes[newkey] = newval
- updateDialog()
\ No newline at end of file
+ updateDialog()
diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm
index 4f603c8708b5..d7a5a55ec743 100644
--- a/code/game/objects/structures/ladders.dm
+++ b/code/game/objects/structures/ladders.dm
@@ -182,31 +182,50 @@
update_icon()
-
/obj/structure/ladder/unbreakable/binary
name = "mysterious ladder"
desc = "Where does it go?"
height = 0
id = "lavaland_binary"
var/area_to_place = /area/lavaland/surface/outdoors
+ var/active = FALSE
-/obj/structure/ladder/unbreakable/binary/Initialize()
- if(area_to_place)
- var/turf/T = safepick(get_area_turfs(area_to_place))
+/obj/structure/ladder/unbreakable/binary/proc/ActivateAlmonds()
+ if(area_to_place && !active)
+ var/turf/T = getTargetTurf()
if(T)
var/obj/structure/ladder/unbreakable/U = new (T)
U.id = id
U.height = height+1
+ LateInitialize() // LateInit both of these to build the links. It's fine.
+ U.LateInitialize()
for(var/turf/TT in range(2,U))
- TT.TerraformTurf(/turf/open/indestructible/binary, /turf/open/indestructible/binary)
- return ..()
+ TT.TerraformTurf(/turf/open/indestructible/binary, /turf/open/indestructible/binary, CHANGETURF_INHERIT_AIR)
+ active = TRUE
+/obj/structure/ladder/unbreakable/binary/proc/getTargetTurf()
+ var/list/turfList = get_area_turfs(area_to_place)
+ while (turfList.len && !.)
+ var/i = rand(1, turfList.len)
+ var/turf/potentialTurf = turfList[i]
+ if (is_centcom_level(potentialTurf.z)) // These ladders don't lead to centcom.
+ turfList.Cut(i,i+1)
+ continue
+ if(!istype(potentialTurf, /turf/open/lava) && !potentialTurf.density) // Or inside dense turfs or lava
+ var/clear = TRUE
+ for(var/obj/O in potentialTurf) // Let's not place these on dense objects either. Might be funny though.
+ if(O.density)
+ clear = FALSE
+ break
+ if(clear)
+ . = potentialTurf
+ if (!.)
+ turfList.Cut(i,i+1)
/obj/structure/ladder/unbreakable/binary/space
id = "space_binary"
area_to_place = /area/space
-
/obj/structure/ladder/unbreakable/binary/unlinked //Crew gets to complete one
id = "unlinked_binary"
area_to_place = null
diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm
index b0e46b8aa4be..8e6bd56d810f 100644
--- a/code/game/turfs/change_turf.dm
+++ b/code/game/turfs/change_turf.dm
@@ -114,6 +114,23 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
return W
+/turf/open/ChangeTurf(path, list/new_baseturfs, flags)
+ if ((flags & CHANGETURF_INHERIT_AIR) && ispath(path, /turf/open))
+ SSair.remove_from_active(src)
+ var/stashed_air = air
+ air = null // so that it doesn't get deleted
+ . = ..()
+ if (!. || . == src) // changeturf failed or didn't do anything
+ air = stashed_air
+ return
+ var/turf/open/newTurf = .
+ if (!istype(newTurf.air, /datum/gas_mixture/immutable/space))
+ QDEL_NULL(newTurf.air)
+ newTurf.air = stashed_air
+ SSair.add_to_active(newTurf)
+ else
+ return ..()
+
// Take off the top layer turf and replace it with the next baseturf down
/turf/proc/ScrapeAway(amount=1, flags)
if(!amount)
@@ -251,7 +268,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
/turf/open/AfterChange(flags)
..()
RemoveLattice()
- if(!(flags & CHANGETURF_IGNORE_AIR))
+ if(!(flags & (CHANGETURF_IGNORE_AIR | CHANGETURF_INHERIT_AIR)))
Assimilate_Air()
//////Assimilate Air//////
@@ -284,4 +301,4 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
/turf/proc/ReplaceWithLattice()
ScrapeAway()
- new /obj/structure/lattice(locate(x, y, z))
\ No newline at end of file
+ new /obj/structure/lattice(locate(x, y, z))