diff --git a/code/__DEFINES/turf_flags.dm b/code/__DEFINES/turf_flags.dm
index f71335e1f0..5ceb6f2e2e 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/__HELPERS/priority_announce.dm b/code/__HELPERS/priority_announce.dm
index 9b6b601e69..bbaf7b275d 100644
--- a/code/__HELPERS/priority_announce.dm
+++ b/code/__HELPERS/priority_announce.dm
@@ -55,7 +55,7 @@
for(var/mob/M in GLOB.player_list)
if(!isnewplayer(M) && M.can_hear())
- to_chat(M, "[title]
[message]
")
+ to_chat(M, "[html_encode(title)]
[html_encode(message)]
")
if(M.client.prefs.toggles & SOUND_ANNOUNCEMENTS)
if(alert)
SEND_SOUND(M, sound('sound/misc/notice1.ogg'))
diff --git a/code/datums/components/storage/concrete/bag_of_holding.dm b/code/datums/components/storage/concrete/bag_of_holding.dm
index 765889849b..1d265fb9ef 100644
--- a/code/datums/components/storage/concrete/bag_of_holding.dm
+++ b/code/datums/components/storage/concrete/bag_of_holding.dm
@@ -22,6 +22,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/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index 702583d01a..0d72a08f1f 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -38,8 +38,7 @@
/obj/machinery/door/window/Destroy()
density = FALSE
- for(var/I in debris)
- qdel(I)
+ QDEL_LIST(debris)
if(obj_integrity == 0)
playsound(src, "shatter", 70, 1)
electronics = null
diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm
index 139769e269..d64ae75e2c 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/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
index faf5574374..52032e9bb3 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
@@ -20,6 +20,7 @@
new /obj/item/clothing/suit/armor/vest/capcarapace/alt(src)
new /obj/item/clothing/head/caphat/parade(src)
new /obj/item/clothing/suit/captunic(src)
+ new /obj/item/clothing/under/rank/captain/femformal(src) //citadel edit
new /obj/item/clothing/head/crown/fancy(src)
new /obj/item/cartridge/captain(src)
new /obj/item/storage/box/silver_ids(src)
diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm
index 4f603c8708..d7a5a55ec7 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/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 197b031c79..aa87410d2c 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -187,8 +187,7 @@
debris += new /obj/item/shard
/obj/structure/table/glass/Destroy()
- for(var/i in debris)
- qdel(i)
+ QDEL_LIST(debris)
. = ..()
/obj/structure/table/glass/Crossed(atom/movable/AM)
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 37abe17121..f94d055391 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -292,6 +292,7 @@
var/obj/item/I = i
I.forceMove(drop_location())
transfer_fingerprints_to(I)
+ debris -= I
qdel(src)
update_nearby_icons()
diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm
index b0e46b8aa4..8e6bd56d81 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))
diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm
index a19ab3c100..54af4b5167 100644
--- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm
+++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm
@@ -54,6 +54,7 @@
return
var/list/refs = list()
+ var/where_used = FALSE
for(var/list/query_tree in querys)
var/list/from_objs = list()
var/list/select_types = list()
@@ -82,6 +83,7 @@
objs_all = objs.len
if("where" in query_tree)
+ where_used = TRUE
var/objs_temp = objs
objs = list()
for(var/datum/d in objs_temp)
@@ -119,7 +121,7 @@
var/end_time = REALTIMEOFDAY
end_time -= start_time
return list("SDQL query results: [query_text]",\
- "SDQL query completed: [objs_all] objects selected by path, and [objs_eligible] objects executed on after WHERE filtering if applicable.",\
+ "SDQL query completed: [objs_all] objects selected by path, and [where_used ? objs_eligible : objs_all] objects executed on after WHERE filtering if applicable.",\
"SDQL query took [DisplayTimeText(end_time)] to complete.") + refs
/proc/SDQL_qdel_datum(datum/d)
diff --git a/code/modules/projectiles/ammunition/energy/gravity.dm b/code/modules/projectiles/ammunition/energy/gravity.dm
index f549a5b5e4..be3a4494cd 100644
--- a/code/modules/projectiles/ammunition/energy/gravity.dm
+++ b/code/modules/projectiles/ammunition/energy/gravity.dm
@@ -7,8 +7,8 @@
var/obj/item/gun/energy/gravity_gun/gun
/obj/item/ammo_casing/energy/gravityrepulse/Initialize(mapload, obj/item/gun/energy/gravity_gun/G)
- . = ..()
gun = G
+ . = ..()
/obj/item/ammo_casing/energy/gravityattract
projectile_type = /obj/item/projectile/gravityattract
@@ -20,8 +20,8 @@
/obj/item/ammo_casing/energy/gravityattract/Initialize(mapload, obj/item/gun/energy/gravity_gun/G)
- . = ..()
gun = G
+ . = ..()
/obj/item/ammo_casing/energy/gravitychaos
projectile_type = /obj/item/projectile/gravitychaos
@@ -32,5 +32,5 @@
var/obj/item/gun/energy/gravity_gun/gun
/obj/item/ammo_casing/energy/gravitychaos/Initialize(mapload, obj/item/gun/energy/gravity_gun/G)
- . = ..()
gun = G
+ . = ..()
diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm
index 3aec44ded3..89f1eb85b9 100644
--- a/code/modules/research/designs/machine_designs.dm
+++ b/code/modules/research/designs/machine_designs.dm
@@ -14,7 +14,7 @@
name = "Machine Design (Circulator Board)"
desc = "The circuit board for a circulator."
id = "circulator"
- build_path = /obj/machinery/atmospherics/components/binary/circulator
+ build_path = /obj/item/circuitboard/machine/circulator
category = list ("Engineering Machinery")
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING
@@ -22,7 +22,7 @@
name = "Machine Design (TEG Board)"
desc = "The circuit board for a TEG."
id = "teg"
- build_path = /obj/machinery/power/generator
+ build_path = /obj/item/circuitboard/machine/generator
category = list ("Engineering Machinery")
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING
diff --git a/html/changelogs/AutoChangeLog-pr-7294.yml b/html/changelogs/AutoChangeLog-pr-7294.yml
new file mode 100644
index 0000000000..8ac886a45d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-7294.yml
@@ -0,0 +1,4 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - bugfix: "Printing the TEG and circulator boards no longer prints the completed machinery instead."
diff --git a/html/changelogs/AutoChangeLog-pr-7327.yml b/html/changelogs/AutoChangeLog-pr-7327.yml
new file mode 100644
index 0000000000..03f67c3307
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-7327.yml
@@ -0,0 +1,9 @@
+author: "Naksu"
+delete-after: True
+changes:
+ - tweak: "The ladders in the tear in the fabric of reality no longer spawn their endpoints when the area is loaded, but only when the tear is made accessible via a BoH bomb."
+ - tweak: "CentCom is no longer accessible via the space ladder in the tear."
+ - tweak: "The lavaland endpoint can no longer spawn completely surrounded by lava, unless it spawns on an island"
+ - code_imp: "ChangeTurf can now conditionally inherit the air of the turf it is replacing, via the CHANGETURF_INHERIT_AIR flag."
+ - bugfix: "when ladder endpoints are created, the binary turfs that are created inherit the air of the turfs they are replacing. This means the lavaland ladder endpoint will have the lavaland airmix, instead of a vacuum."
+ - code_imp: "navigation beacons are now properly deregistered from their Z-level list and re-registered on the correct one if moved across Z-levels by an effect such as teleportation or a BoH-induced chasm."
diff --git a/modular_citadel/code/modules/clothing/under/under.dm b/modular_citadel/code/modules/clothing/under/under.dm
index 7ab8362a83..94c28fb1c3 100644
--- a/modular_citadel/code/modules/clothing/under/under.dm
+++ b/modular_citadel/code/modules/clothing/under/under.dm
@@ -30,4 +30,16 @@
icon_state = "tssuit"
alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi'
item_state = "r_suit"
- can_adjust = FALSE
\ No newline at end of file
+ can_adjust = FALSE
+
+/obj/item/clothing/under/rank/captain/femformal
+ name ="captain's female formal outfit"
+ desc = ""
+ icon = 'modular_citadel/icons/obj/clothing/cit_clothes.dmi'
+ icon_state = "lewdcap"
+ icon_override = 'modular_citadel/icons/mob/citadel/uniforms.dmi'
+ item_state = "lewdcap"
+ item_color = "lewdcap"
+ can_adjust = FALSE
+ sensor_mode = SENSOR_COORDS //it's still a captain's suit nerd
+ random_sensor = FALSE
diff --git a/modular_citadel/icons/mob/citadel/uniforms.dmi b/modular_citadel/icons/mob/citadel/uniforms.dmi
index f34bfd6e45..855872e9ab 100644
Binary files a/modular_citadel/icons/mob/citadel/uniforms.dmi and b/modular_citadel/icons/mob/citadel/uniforms.dmi differ
diff --git a/modular_citadel/icons/obj/clothing/cit_clothes.dmi b/modular_citadel/icons/obj/clothing/cit_clothes.dmi
index 01ad0d37f9..8cc6ca2950 100644
Binary files a/modular_citadel/icons/obj/clothing/cit_clothes.dmi and b/modular_citadel/icons/obj/clothing/cit_clothes.dmi differ