diff --git a/_maps/shuttles/emergency_saltmine.dmm b/_maps/shuttles/emergency_saltmine.dmm
new file mode 100644
index 0000000000..8cd5bdbcf2
--- /dev/null
+++ b/_maps/shuttles/emergency_saltmine.dmm
@@ -0,0 +1,947 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"aa" = (
+/turf/template_noop,
+/area/template_noop)
+"ab" = (
+/turf/closed/wall/clockwork,
+/area/shuttle/escape)
+"ac" = (
+/turf/closed/wall/mineral/titanium,
+/area/shuttle/escape)
+"ad" = (
+/obj/effect/spawner/structure/window/shuttle,
+/obj/effect/decal/cleanable/salt,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"ae" = (
+/turf/closed/wall/mineral/titanium,
+/turf/closed/wall/mineral/cult,
+/area/shuttle/escape)
+"af" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/destructible/clockwork/trap/trigger/pressure_sensor,
+/obj/structure/destructible/clockwork/trap/brass_skewer,
+/turf/open/indestructible/clock_spawn_room,
+/area/shuttle/escape)
+"ag" = (
+/obj/structure/shuttle/engine/propulsion/right{
+ dir = 4
+ },
+/turf/open/floor/plating/airless,
+/area/shuttle/escape)
+"ah" = (
+/turf/closed/wall/mineral/titanium/nodiagonal,
+/area/shuttle/escape)
+"ai" = (
+/obj/machinery/computer/emergency_shuttle,
+/obj/effect/decal/cleanable/salt,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"aj" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/item/card/emag/fake,
+/obj/machinery/light{
+ dir = 1
+ },
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"ak" = (
+/obj/effect/decal/cleanable/salt,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"al" = (
+/obj/effect/decal/cleanable/salt,
+/turf/open/floor/plasteel/cult,
+/area/shuttle/escape)
+"am" = (
+/obj/effect/decal/cleanable/salt,
+/obj/effect/decal/cleanable/crayon,
+/turf/open/floor/plasteel/cult,
+/area/shuttle/escape)
+"an" = (
+/obj/machinery/light{
+ dir = 1
+ },
+/obj/effect/decal/cleanable/salt,
+/turf/open/floor/plasteel/cult,
+/area/shuttle/escape)
+"ao" = (
+/obj/effect/decal/cleanable/salt,
+/obj/item/tome,
+/obj/structure/table/reinforced,
+/turf/open/floor/plasteel/cult,
+/area/shuttle/escape)
+"ap" = (
+/obj/effect/decal/cleanable/salt,
+/obj/item/clothing/gloves/clockwork,
+/obj/structure/destructible/clockwork/trap/trigger/pressure_sensor,
+/obj/structure/destructible/clockwork/trap/brass_skewer,
+/turf/open/indestructible/clock_spawn_room,
+/area/shuttle/escape)
+"aq" = (
+/obj/effect/decal/cleanable/salt,
+/obj/item/clothing/suit/armor/clockwork,
+/obj/structure/destructible/clockwork/trap/trigger/pressure_sensor,
+/obj/structure/destructible/clockwork/trap/brass_skewer,
+/turf/open/indestructible/clock_spawn_room,
+/area/shuttle/escape)
+"ar" = (
+/obj/machinery/light{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/salt,
+/obj/item/clothing/shoes/clockwork,
+/obj/structure/destructible/clockwork/trap/trigger/pressure_sensor,
+/obj/structure/destructible/clockwork/trap/brass_skewer,
+/turf/open/indestructible/clock_spawn_room,
+/area/shuttle/escape)
+"as" = (
+/obj/structure/shuttle/engine/propulsion{
+ dir = 4
+ },
+/turf/open/floor/plating/airless,
+/area/shuttle/escape)
+"at" = (
+/obj/effect/decal/cleanable/salt,
+/obj/machinery/portable_atmospherics/canister/water_vapor,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"au" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/structure/holosign/wetsign,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"av" = (
+/obj/machinery/door/airlock/command/glass{
+ name = "bridge door";
+ req_access_txt = "19";
+ secondsElectrified = -1
+ },
+/obj/effect/decal/cleanable/salt,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"aw" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/destructible/clockwork/trap/trigger/pressure_sensor,
+/turf/open/indestructible/clock_spawn_room,
+/area/shuttle/escape)
+"ax" = (
+/obj/structure/shuttle/engine/propulsion/left{
+ dir = 4
+ },
+/turf/open/floor/plating/airless,
+/area/shuttle/escape)
+"ay" = (
+/obj/machinery/light,
+/obj/effect/decal/cleanable/salt,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"az" = (
+/turf/open/floor/plasteel/cult,
+/turf/closed/wall/mineral/cult,
+/area/shuttle/escape)
+"aA" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/item/twohanded/spear,
+/obj/item/device/assembly/flash/handheld,
+/turf/open/floor/plasteel/cult,
+/area/shuttle/escape)
+"aB" = (
+/obj/structure/table/reinforced,
+/obj/effect/decal/cleanable/salt,
+/obj/item/greentext,
+/obj/item/banhammer,
+/turf/open/floor/plasteel/cult,
+/area/shuttle/escape)
+"aC" = (
+/obj/effect/decal/cleanable/salt,
+/turf/open/indestructible/clock_spawn_room,
+/area/shuttle/escape)
+"aD" = (
+/obj/machinery/door/airlock/security/glass{
+ name = "security airlock";
+ req_access_txt = "63";
+ secondsElectrified = -1
+ },
+/obj/effect/decal/cleanable/salt,
+/turf/open/floor/plasteel/cult,
+/area/shuttle/escape)
+"aE" = (
+/obj/structure/sign/poster/contraband/energy_swords,
+/turf/closed/wall/clockwork,
+/area/shuttle/escape)
+"aF" = (
+/obj/structure/sign/poster/contraband/revolver,
+/turf/closed/wall/clockwork,
+/area/shuttle/escape)
+"aG" = (
+/obj/effect/decal/cleanable/salt,
+/obj/machinery/door/airlock/clockwork{
+ req_access = null
+ },
+/turf/open/indestructible/clock_spawn_room,
+/area/shuttle/escape)
+"aH" = (
+/obj/structure/sign/poster/contraband/kudzu,
+/turf/closed/wall/clockwork,
+/area/shuttle/escape)
+"aI" = (
+/obj/structure/sign/poster/contraband/busty_backdoor_xeno_babes_6,
+/turf/closed/wall/clockwork,
+/area/shuttle/escape)
+"aJ" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/item/reagent_containers/glass/beaker/waterbottle/large,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"aK" = (
+/obj/effect/decal/cleanable/salt,
+/obj/item/grown/bananapeel,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"aL" = (
+/obj/structure/table/reinforced,
+/obj/machinery/light{
+ dir = 1
+ },
+/obj/effect/decal/cleanable/salt,
+/obj/item/clothing/mask/vape,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"aM" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/glass,
+/obj/item/toy/plush/plushvar,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"aN" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/item/reagent_containers/food/snacks/salad/validsalad,
+/obj/item/toy/figure/warden,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"aO" = (
+/obj/item/grown/bananapeel,
+/obj/item/storage/backpack,
+/obj/effect/decal/cleanable/salt,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"aP" = (
+/obj/structure/table/reinforced,
+/obj/effect/decal/cleanable/salt,
+/obj/item/gun/ballistic/automatic/c20r/toy/unrestricted,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"aQ" = (
+/obj/item/soap/deluxe,
+/obj/effect/decal/cleanable/salt,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"aR" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/glass,
+/obj/item/toy/spinningtoy,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"aS" = (
+/obj/structure/table/reinforced,
+/obj/effect/decal/cleanable/salt,
+/obj/item/toy/katana,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"aT" = (
+/obj/machinery/door/airlock/titanium,
+/obj/item/soap/deluxe,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"aU" = (
+/obj/effect/decal/cleanable/salt,
+/obj/item/toy/syndicateballoon,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"aW" = (
+/obj/structure/table/reinforced,
+/obj/effect/decal/cleanable/salt,
+/obj/item/clothing/mask/vape,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"aX" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/glass,
+/obj/item/toy/plush/narplush,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"aY" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/item/reagent_containers/food/snacks/salad/validsalad,
+/obj/item/toy/figure/hos,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"ba" = (
+/obj/structure/table/reinforced,
+/obj/effect/decal/cleanable/salt,
+/obj/item/gun/ballistic/revolver/reverse,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bb" = (
+/obj/structure/table/reinforced,
+/obj/effect/decal/cleanable/salt,
+/obj/item/toy/sword,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bc" = (
+/obj/machinery/light/small,
+/obj/item/soap/deluxe,
+/obj/effect/decal/cleanable/salt,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bd" = (
+/obj/machinery/door/airlock/titanium,
+/obj/docking_port/mobile/emergency{
+ dheight = 0;
+ dir = 8;
+ dwidth = 6;
+ height = 18;
+ name = "Saltmine";
+ port_direction = 4;
+ timid = 1;
+ width = 14
+ },
+/obj/item/soap/deluxe,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"be" = (
+/obj/effect/decal/cleanable/salt,
+/mob/living/simple_animal/bot/secbot/beepsky,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bf" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/item/reagent_containers/glass/beaker/waterbottle/large,
+/obj/structure/window/plasma/reinforced,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bg" = (
+/obj/effect/decal/cleanable/salt,
+/obj/item/grown/bananapeel,
+/obj/structure/window/plasma/reinforced,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bh" = (
+/obj/structure/table/reinforced,
+/obj/effect/decal/cleanable/salt,
+/obj/effect/decal/cleanable/salt,
+/obj/item/clothing/mask/vape,
+/obj/structure/window/plasma/reinforced,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bi" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/window/plasma/reinforced,
+/obj/structure/table/glass,
+/obj/item/toy/plush/nukeplushie,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bj" = (
+/obj/structure/window/plasma/reinforced,
+/obj/effect/decal/cleanable/salt,
+/obj/item/grown/bananapeel,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bk" = (
+/obj/structure/window/plasma/reinforced,
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/item/reagent_containers/food/snacks/salad/validsalad,
+/obj/item/toy/figure/secofficer,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bl" = (
+/obj/structure/window/plasma/reinforced,
+/obj/effect/decal/cleanable/salt,
+/obj/item/grown/bananapeel,
+/obj/item/storage/backpack,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bm" = (
+/obj/structure/window/plasma/reinforced,
+/obj/machinery/light{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/item/gun/ballistic/automatic/l6_saw/toy/unrestricted,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bn" = (
+/obj/structure/sign/poster/contraband/lizard,
+/turf/closed/wall/mineral/titanium/nodiagonal,
+/area/shuttle/escape)
+"bo" = (
+/obj/structure/sign/poster/contraband/lusty_xenomorph,
+/turf/closed/wall/mineral/titanium/nodiagonal,
+/area/shuttle/escape)
+"bp" = (
+/obj/structure/sign/poster/contraband/grey_tide,
+/turf/closed/wall/mineral/titanium/nodiagonal,
+/area/shuttle/escape)
+"bq" = (
+/obj/structure/sign/poster/contraband/fun_police,
+/turf/closed/wall/mineral/titanium,
+/area/shuttle/escape)
+"br" = (
+/obj/structure/sign/poster/official/wtf_is_co2,
+/turf/closed/wall/mineral/titanium,
+/area/shuttle/escape)
+"bs" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/item/reagent_containers/glass/beaker/waterbottle/large,
+/obj/structure/window/plasma/reinforced{
+ dir = 1
+ },
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bt" = (
+/obj/effect/decal/cleanable/salt,
+/obj/item/grown/bananapeel,
+/obj/structure/window/plasma/reinforced{
+ dir = 1
+ },
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bu" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/item/clothing/head/collectable/wizard,
+/obj/structure/window/plasma/reinforced{
+ dir = 1
+ },
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bv" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/glass,
+/obj/item/clothing/head/kitty/genuine,
+/obj/structure/window/plasma/reinforced{
+ dir = 1
+ },
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bw" = (
+/obj/effect/decal/cleanable/salt,
+/obj/item/grown/bananapeel,
+/obj/structure/window/plasma/reinforced{
+ dir = 1
+ },
+/obj/item/device/assembly/flash,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bx" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/structure/window/plasma/reinforced{
+ dir = 1
+ },
+/obj/item/toy/plush/lizardplushie,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"by" = (
+/obj/effect/decal/cleanable/salt,
+/turf/closed/wall/mineral/titanium,
+/area/shuttle/escape)
+"bz" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/item/clothing/suit/wizrobe,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bA" = (
+/obj/structure/table/glass,
+/obj/effect/decal/cleanable/salt,
+/obj/item/clothing/head/rabbitears,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bB" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/item/stack/sheet/animalhide/lizard,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bC" = (
+/obj/structure/table/reinforced,
+/obj/effect/decal/cleanable/salt,
+/obj/item/bikehorn,
+/obj/item/organ/eyes/moth,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bD" = (
+/obj/effect/decal/cleanable/salt,
+/turf/open/floor/fakepit,
+/area/shuttle/escape)
+"bE" = (
+/obj/structure/table/glass,
+/obj/effect/decal/cleanable/salt,
+/obj/item/storage/firstaid/fire,
+/turf/open/floor/fakepit,
+/area/shuttle/escape)
+"bF" = (
+/obj/machinery/light,
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/item/gun/magic/wand/resurrection/inert,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bG" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/glass,
+/obj/item/clothing/head/rabbitears,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bH" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/item/reagent_containers/food/drinks/bottle/lizardwine,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bI" = (
+/turf/open/chasm,
+/area/shuttle/escape)
+"bJ" = (
+/obj/structure/table/glass,
+/obj/machinery/light{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/salt,
+/obj/item/clothing/mask/frog,
+/obj/item/storage/box/hug/medical,
+/turf/open/floor/fakepit,
+/area/shuttle/escape)
+"bK" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/glass,
+/obj/item/clothing/head/kitty/genuine,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bL" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/item/toy/plush/lizardplushie,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"bM" = (
+/obj/effect/decal/cleanable/salt,
+/obj/machinery/sleeper/syndie,
+/turf/open/floor/fakepit,
+/area/shuttle/escape)
+"bN" = (
+/obj/structure/table/glass,
+/obj/effect/decal/cleanable/salt,
+/obj/item/grenade/flashbang,
+/obj/item/grenade/flashbang,
+/obj/item/grenade/flashbang,
+/obj/item/grenade/flashbang,
+/obj/item/grenade/flashbang,
+/turf/open/floor/fakepit,
+/area/shuttle/escape)
+"jz" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/statue/plasma/scientist{
+ desc = "This statue is suitably made from tears of a certain man, you can still hear him crying to this day.";
+ oreAmount = 0
+ },
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"oC" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/window,
+/obj/structure/window{
+ dir = 4
+ },
+/mob/living/simple_animal/hostile/retaliate/clown{
+ health = 200;
+ maxHealth = 200
+ },
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"rH" = (
+/obj/effect/decal/cleanable/salt,
+/obj/item/mecha_parts/mecha_equipment/weapon/honker,
+/obj/structure/table/reinforced,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"vf" = (
+/obj/effect/spawner/structure/window/shuttle,
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"wp" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/destructible/clockwork/trap/trigger/pressure_sensor,
+/obj/structure/destructible/clockwork/trap/brass_skewer,
+/obj/item/device/radio/beacon,
+/turf/open/indestructible/clock_spawn_room,
+/area/shuttle/escape)
+"xd" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/item/codespeak_manual/unlimited,
+/turf/open/floor/plasteel/cult,
+/area/shuttle/escape)
+"xi" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/item/reagent_containers/food/snacks/grown/citrus/orange,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"Ac" = (
+/obj/effect/decal/cleanable/salt,
+/mob/living/simple_animal/bot/honkbot,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"CB" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/window{
+ dir = 4
+ },
+/mob/living/simple_animal/hostile/retaliate/clown{
+ health = 200;
+ maxHealth = 200
+ },
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"Ho" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/window/plasma/reinforced{
+ dir = 1
+ },
+/obj/structure/table/reinforced,
+/obj/item/clothing/neck/petcollar,
+/obj/item/restraints/handcuffs,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"HA" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/table/reinforced,
+/obj/item/clothing/under/schoolgirl,
+/obj/item/clothing/head/kitty,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"Iq" = (
+/obj/effect/decal/cleanable/salt,
+/obj/structure/bed/dogbed/ian,
+/obj/item/stack/sheet/animalhide/corgi,
+/obj/item/reagent_containers/food/snacks/meat/slab/corgi,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"LR" = (
+/obj/effect/decal/cleanable/salt,
+/obj/mecha/combat/honker{
+ max_integrity = 60
+ },
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+"Uc" = (
+/obj/effect/decal/cleanable/salt,
+/obj/item/grown/bananapeel,
+/obj/structure/table/reinforced,
+/obj/item/clothing/suit/armor/reactive/table,
+/turf/open/floor/fakespace,
+/area/shuttle/escape)
+
+(1,1,1) = {"
+aa
+aa
+ac
+ac
+ac
+ac
+ad
+ad
+ad
+ad
+ad
+ac
+aa
+aa
+"}
+(2,1,1) = {"
+aa
+ac
+ah
+LR
+CB
+vf
+jz
+aU
+aU
+aU
+jz
+ah
+ac
+aa
+"}
+(3,1,1) = {"
+aa
+ac
+ai
+oC
+xi
+av
+Ac
+ak
+be
+ak
+Ac
+ak
+ac
+aa
+"}
+(4,1,1) = {"
+aa
+ac
+aj
+rH
+ay
+ac
+aJ
+aJ
+bf
+bs
+aJ
+aJ
+ac
+aa
+"}
+(5,1,1) = {"
+aa
+ac
+ak
+at
+ak
+ac
+aK
+aK
+bg
+bt
+aK
+aK
+ac
+aa
+"}
+(6,1,1) = {"
+aa
+ac
+Iq
+au
+ak
+ac
+aL
+aW
+bh
+bu
+bz
+bF
+ah
+ac
+"}
+(7,1,1) = {"
+aa
+ae
+ae
+av
+az
+ae
+aK
+aK
+bg
+bt
+aK
+aK
+aK
+ac
+"}
+(8,1,1) = {"
+aa
+ae
+al
+al
+al
+az
+aM
+aX
+bi
+bv
+bA
+bG
+bK
+ac
+"}
+(9,1,1) = {"
+aa
+ae
+am
+al
+aA
+aD
+aK
+aK
+bj
+bw
+aK
+aK
+aK
+ad
+"}
+(10,1,1) = {"
+aa
+ae
+an
+al
+al
+az
+aN
+aY
+bk
+bx
+bB
+bH
+bL
+ad
+"}
+(11,1,1) = {"
+aa
+ae
+al
+al
+al
+ae
+aO
+aO
+bl
+bt
+aK
+aK
+aK
+ad
+"}
+(12,1,1) = {"
+aa
+ae
+ao
+xd
+aB
+ae
+aP
+ba
+bm
+Ho
+aK
+Uc
+HA
+ac
+"}
+(13,1,1) = {"
+ab
+ab
+ab
+ab
+ab
+aE
+aQ
+aQ
+bn
+ah
+bC
+ad
+ac
+ac
+"}
+(14,1,1) = {"
+ab
+wp
+ap
+af
+af
+aF
+aR
+aR
+bo
+by
+bD
+bD
+bM
+ac
+"}
+(15,1,1) = {"
+ab
+wp
+aq
+af
+af
+aG
+aQ
+aQ
+bp
+by
+bD
+bI
+bD
+ac
+"}
+(16,1,1) = {"
+ab
+wp
+ar
+aw
+aC
+aH
+aS
+bb
+bq
+ac
+bE
+bJ
+bN
+ac
+"}
+(17,1,1) = {"
+ab
+ab
+ab
+ab
+ab
+aI
+aQ
+bc
+br
+ac
+ac
+ac
+ac
+ac
+"}
+(18,1,1) = {"
+ac
+ag
+as
+ax
+ac
+ac
+aT
+bd
+ac
+ah
+ag
+as
+ax
+ac
+"}
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 598fb8b7a2..be3b897e5c 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1506,10 +1506,13 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
// Makes a call in the context of a different usr
// Use sparingly
-/world/proc/PushUsr(mob/M, datum/callback/CB)
+/world/proc/PushUsr(mob/M, datum/callback/CB, ...)
var/temp = usr
usr = M
- . = CB.Invoke()
+ if (length(args) > 2)
+ . = CB.Invoke(arglist(args.Copy(3)))
+ else
+ . = CB.Invoke()
usr = temp
//Returns a list of all servants of Ratvar and observers.
diff --git a/code/_onclick/hud/ai.dm b/code/_onclick/hud/ai.dm
index b2af85d1b0..f50cf8dc87 100644
--- a/code/_onclick/hud/ai.dm
+++ b/code/_onclick/hud/ai.dm
@@ -162,7 +162,7 @@
if(..())
return
var/mob/living/silicon/S = usr
- S.sensor_mode()
+ S.toggle_sensors()
/datum/hud/ai
diff --git a/code/datums/callback.dm b/code/datums/callback.dm
index 6e92d41c6d..c603be85b7 100644
--- a/code/datums/callback.dm
+++ b/code/datums/callback.dm
@@ -78,11 +78,13 @@
if(W)
var/mob/M = W.resolve()
if(M)
+ if (length(args))
+ return world.PushUsr(arglist(list(M, src) + args))
return world.PushUsr(M, src)
-
+
if (!object)
return
-
+
var/list/calling_arguments = arguments
if (length(args))
if (length(arguments))
@@ -104,11 +106,13 @@
if(W)
var/mob/M = W.resolve()
if(M)
+ if (length(args))
+ return world.PushUsr(arglist(list(M, src) + args))
return world.PushUsr(M, src)
-
+
if (!object)
return
-
+
var/list/calling_arguments = arguments
if (length(args))
if (length(arguments))
diff --git a/code/datums/holocall.dm b/code/datums/holocall.dm
index 342e84974a..d19e8be2e1 100644
--- a/code/datums/holocall.dm
+++ b/code/datums/holocall.dm
@@ -202,6 +202,12 @@
var/list/entries = list()
var/language = /datum/language/common //Initial language, can be changed by HOLORECORD_LANGUAGE entries
+/datum/holorecord/proc/set_caller_image(mob/user)
+ var/olddir = user.dir
+ user.setDir(SOUTH)
+ caller_image = getFlatIcon(user)
+ user.setDir(olddir)
+
/obj/item/disk/holodisk
name = "holorecord disk"
desc = "Stores recorder holocalls."
@@ -278,7 +284,7 @@
else
var/datum/preset_holoimage/H = new preset_image_type
record.caller_image = H.build_image()
-
+
//These build caller image from outfit and some additional data, for use by mappers for ruin holorecords
/datum/preset_holoimage
var/nonhuman_mobtype //Fill this if you just want something nonhuman
diff --git a/code/datums/shuttles.dm b/code/datums/shuttles.dm
index 404c584fd4..b5775f5874 100644
--- a/code/datums/shuttles.dm
+++ b/code/datums/shuttles.dm
@@ -87,6 +87,7 @@
description = "A respectable mid-sized shuttle that first saw service shuttling Nanotrasen crew to and from their asteroid belt embedded facilities."
credit_cost = 3000
+
/datum/map_template/shuttle/emergency/bar
suffix = "bar"
name = "The Emergency Escape Bar"
@@ -109,6 +110,18 @@
admin_notes = "This shuttle will likely crush escape, killing anyone there."
credit_cost = -5000
+/datum/map_template/shuttle/emergency/saltmine
+ suffix = "saltmine"
+ name = "The Saltmine"
+ description = "Contains everything that upsets you."
+ admin_notes = "Don't forget: You're here forever."
+ credit_cost = 5000
+
+/datum/map_template/shuttle/emergency/saltmine/prerequisites_met()
+ if("revenant" in SSshuttle.shuttle_purchase_requirements_met)
+ return TRUE
+ return FALSE
+
/datum/map_template/shuttle/emergency/luxury
suffix = "luxury"
name = "Luxury Shuttle"
diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm
index 084bb29591..4bd374b68c 100644
--- a/code/game/machinery/doppler_array.dm
+++ b/code/game/machinery/doppler_array.dm
@@ -110,11 +110,15 @@ GLOBAL_LIST_EMPTY(doppler_arrays)
if(!istype(linked_techweb))
say("Warning: No linked research system!")
return
- var/adjusted = orig_light - 10 - linked_techweb.max_bomb_value
+ var/adjusted = orig_light - 20 - linked_techweb.max_bomb_value
if(adjusted <= 0)
say("Explosion not large enough for research calculations.")
return
var/point_gain = techweb_scale_bomb(adjusted)
+ if(point_gain <= 0)
+ say("Explosion not large enough for research calculations.")
+ return
+ var/point_gain = techweb_scale_bomb(adjusted)
if(point_gain <= 0)
say("Explosion not large enough for research calculations.")
return
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index 12fe90f04d..0642f1bef8 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -58,6 +58,7 @@ Possible to do for anyone motivated enough:
var/static/force_answer_call = FALSE //Calls will be automatically answered after a couple rings, here for debugging
var/static/list/holopads = list()
var/obj/effect/overlay/holoray/ray
+ var/offset = FALSE
/obj/machinery/holopad/Initialize()
. = ..()
@@ -279,7 +280,16 @@ Possible to do for anyone motivated enough:
record_stop()
else if(href_list["record_clear"])
record_clear()
-
+ else if(href_list["offset"])
+ offset++
+ if (offset > 4)
+ offset = FALSE
+ var/turf/new_turf
+ if (!offset)
+ new_turf = get_turf(src)
+ else
+ new_turf = get_step(src, GLOB.cardinals[offset])
+ replay_holo.forceMove(new_turf)
updateDialog()
//do not allow AIs to answer calls or people will use it to meta the AI sattelite
@@ -493,7 +503,8 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
replay_mode = TRUE
replay_holo = setup_replay_holo(disk.record)
temp = "Replaying...
"
- temp += "End replay."
+ temp += "Change offset
"
+ temp += "End replay"
SetLightsAndPower()
replay_entry(1)
return
@@ -502,6 +513,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
if(replay_mode)
replay_mode = FALSE
loop_mode = FALSE
+ offset = FALSE
temp = null
QDEL_NULL(replay_holo)
SetLightsAndPower()
@@ -514,16 +526,10 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
record_mode = TRUE
record_start = world.time
record_user = user
- disk.record.caller_image = get_record_icon(user)
+ disk.record.set_caller_image(user)
temp = "Recording...
"
temp += "End recording."
-/obj/machinery/holopad/proc/get_record_icon(mob/living/user)
- var/olddir = user.dir
- user.setDir(SOUTH)
- . = getFlatIcon(user)
- user.setDir(olddir)
-
/obj/machinery/holopad/proc/record_message(mob/living/speaker,message,language)
if(!record_mode)
return
@@ -553,8 +559,10 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
/obj/machinery/holopad/proc/replay_entry(entry_number)
if(!replay_mode)
return
+ if (!disk.record.entries.len) // check for zero entries such as photographs and no text recordings
+ return // and pretty much just display them statically untill manually stopped
if(disk.record.entries.len < entry_number)
- if (loop_mode)
+ if(loop_mode)
entry_number = 1
else
replay_stop()
diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm
index 4ab0dff645..958b9ff8b0 100644
--- a/code/game/objects/items/blueprints.dm
+++ b/code/game/objects/items/blueprints.dm
@@ -191,6 +191,7 @@
var/obj/machinery/door/firedoor/FD = D
FD.CalculateAffectingAreas()
to_chat(usr, "You rename the '[prevname]' to '[str]'.")
+ log_game("[key_name(usr)] has renamed [prevname] to [str]")
interact()
return 1
diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm
index 49d37b05f5..9e83a92847 100644
--- a/code/game/objects/items/cards_ids.dm
+++ b/code/game/objects/items/cards_ids.dm
@@ -78,6 +78,10 @@
return
A.emag_act(user)
+/obj/item/card/emag/fake/afterattack()
+ playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1)
+ return
+
/obj/item/card/id
name = "identification card"
desc = "A card used to provide ID and determine access across the station."
diff --git a/code/game/objects/items/devices/geiger_counter.dm b/code/game/objects/items/devices/geiger_counter.dm
index 64d710be25..c16ef8710e 100644
--- a/code/game/objects/items/devices/geiger_counter.dm
+++ b/code/game/objects/items/devices/geiger_counter.dm
@@ -119,6 +119,7 @@
loop.start()
/obj/item/device/geiger_counter/rad_act(amount)
+ . = ..()
if(amount <= RAD_BACKGROUND_RADIATION || !scanning)
return
current_tick_amount += amount
diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm
index 8f2aaacfb0..9c5fa40c62 100644
--- a/code/game/objects/structures/beds_chairs/chair.dm
+++ b/code/game/objects/structures/beds_chairs/chair.dm
@@ -365,6 +365,7 @@
buildstacktype = /obj/item/stack/tile/brass
buildstackamount = 1
item_chair = null
+ var/turns = 0
/obj/structure/chair/brass/Destroy()
STOP_PROCESSING(SSfastprocess, src)
@@ -373,11 +374,15 @@
/obj/structure/chair/brass/process()
setDir(turn(dir,-90))
playsound(src, 'sound/effects/servostep.ogg', 50, FALSE)
+ turns++
+ if(turns >= 8)
+ STOP_PROCESSING(SSfastprocess, src)
/obj/structure/chair/brass/ratvar_act()
return
/obj/structure/chair/brass/AltClick(mob/living/user)
+ turns = 0
if(!user.canUseTopic(src, be_close = TRUE))
return
if(!isprocessing)
diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm
index b88ee9049f..924ccfb3b2 100644
--- a/code/game/objects/structures/mirror.dm
+++ b/code/game/objects/structures/mirror.dm
@@ -89,7 +89,7 @@
name = "magic mirror"
desc = "Turn and face the strange... face."
icon_state = "magic_mirror"
- var/list/races_blacklist = list("skeleton", "agent", "angel", "military_synth", "memezombies", "clockwork golem servant")
+ var/list/races_blacklist = list("skeleton", "agent", "angel", "military_synth", "memezombies", "clockwork golem servant", "android", "synth")
var/list/choosable_races = list()
/obj/structure/mirror/magic/New()
diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm
index 12b37d0e01..da1f941ccc 100644
--- a/code/game/turfs/open.dm
+++ b/code/game/turfs/open.dm
@@ -352,7 +352,9 @@
/turf/open/rad_act(pulse_strength)
+ . = ..()
if (air.gases[/datum/gas/carbon_dioxide] && air.gases[/datum/gas/oxygen])
+ pulse_strength = min(pulse_strength,air.gases[/datum/gas/carbon_dioxide][MOLES]*1000,air.gases[/datum/gas/oxygen][MOLES]*2000) //Ensures matter is conserved properly
air.gases[/datum/gas/carbon_dioxide][MOLES]=max(air.gases[/datum/gas/carbon_dioxide][MOLES]-(pulse_strength/1000),0)
air.gases[/datum/gas/oxygen][MOLES]=max(air.gases[/datum/gas/oxygen][MOLES]-(pulse_strength/2000),0)
air.assert_gas(/datum/gas/pluoxium)
diff --git a/code/modules/antagonists/cult/cult_structures.dm b/code/modules/antagonists/cult/cult_structures.dm
index efe94afb88..ea8e18d7aa 100644
--- a/code/modules/antagonists/cult/cult_structures.dm
+++ b/code/modules/antagonists/cult/cult_structures.dm
@@ -89,13 +89,12 @@
if(cooldowntime > world.time)
to_chat(user, "The magic in [src] is weak, it will be ready to use again in [DisplayTimeText(cooldowntime - world.time)].")
return
- var/choice = alert(user,"You study the schematics etched into the altar...",,"Eldritch Whetstone","Construct Shells","Flask of Unholy Water")
+ var/choice = alert(user,"You study the schematics etched into the altar...",,"Eldritch Whetstone","Construct Shell","Flask of Unholy Water")
var/list/pickedtype = list()
switch(choice)
if("Eldritch Whetstone")
pickedtype += /obj/item/sharpener/cult
- if("Construct Shells")
- pickedtype += /obj/structure/constructshell
+ if("Construct Shell")
pickedtype += /obj/structure/constructshell
if("Flask of Unholy Water")
pickedtype += /obj/item/reagent_containers/glass/beaker/unholywater
diff --git a/code/modules/antagonists/cult/ritual.dm b/code/modules/antagonists/cult/ritual.dm
index 00ec291755..20ac8c88cf 100644
--- a/code/modules/antagonists/cult/ritual.dm
+++ b/code/modules/antagonists/cult/ritual.dm
@@ -138,21 +138,10 @@ This file contains the cult dagger and rune list code
if(isspaceturf(T))
to_chat(user, "You cannot scribe runes in space!")
return FALSE
-
if(locate(/obj/effect/rune) in T)
to_chat(user, "There is already a rune here.")
return FALSE
-
-
if(!is_station_level(T.z) && !is_mining_level(T.z))
to_chat(user, "The veil is not weak enough here.")
-
return FALSE
-
- var/area/A = get_area(T)
- if(A && !A.blob_allowed)
- to_chat(user, "There's a passage in [src] specifically forbidding oyster consumption, triple-frying, and building outside of designated cult zones.")
- return FALSE
-
-
return TRUE
diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm
index 25161c30c5..fc7d6ecc64 100644
--- a/code/modules/antagonists/cult/runes.dm
+++ b/code/modules/antagonists/cult/runes.dm
@@ -316,7 +316,7 @@ structure_check() searches for nearby cultist structures required for the invoca
to_chat(M, "\"I accept this meager sacrifice.\"")
var/obj/item/device/soulstone/stone = new /obj/item/device/soulstone(get_turf(src))
- if(sacrificial.mind)
+ if(sacrificial.mind && !sacrificial.suiciding)
stone.invisibility = INVISIBILITY_MAXIMUM //so it's not picked up during transfer_soul()
stone.transfer_soul("FORCE", sacrificial, usr)
stone.invisibility = 0
diff --git a/code/modules/antagonists/revenant/revenant.dm b/code/modules/antagonists/revenant/revenant.dm
index 5be923ddcc..2c21bd5145 100644
--- a/code/modules/antagonists/revenant/revenant.dm
+++ b/code/modules/antagonists/revenant/revenant.dm
@@ -224,6 +224,7 @@
invisibility = INVISIBILITY_ABSTRACT
revealed = FALSE
ghostize(0)//Don't re-enter invisible corpse
+ SSshuttle.shuttle_purchase_requirements_met |= "revenant"
//reveal, stun, icon updates, cast checks, and essence changing
diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm
index aabbe089fb..67bb932df2 100644
--- a/code/modules/atmospherics/gasmixtures/reactions.dm
+++ b/code/modules/atmospherics/gasmixtures/reactions.dm
@@ -152,6 +152,7 @@
if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY)
ASSERT_GAS(/datum/gas/carbon_dioxide, air) //don't need to assert o2, since if it isn't present we'll never reach this point anyway
+ plasma_burn_rate = min(plasma_burn_rate,cached_gases[/datum/gas/plasma][MOLES],cached_gases[/datum/gas/oxygen][MOLES]/oxygen_burn_rate) //Ensures matter is conserved properly
cached_gases[/datum/gas/plasma][MOLES] = QUANTIZE(cached_gases[/datum/gas/plasma][MOLES] - plasma_burn_rate)
cached_gases[/datum/gas/oxygen][MOLES] = QUANTIZE(cached_gases[/datum/gas/oxygen][MOLES] - (plasma_burn_rate * oxygen_burn_rate))
if (super_saturation)
@@ -207,13 +208,13 @@
var/old_heat_capacity = air.heat_capacity()
var/catalyst_efficency = max(min(cached_gases[/datum/gas/plasma][MOLES]/cached_gases[/datum/gas/tritium][MOLES],MAX_CATALYST_EFFICENCY)-(temperature/FUSION_HEAT_DROPOFF),1)
var/reaction_energy = THERMAL_ENERGY(air)
- var/moles_impurities = air.total_moles()-(cached_gases[/datum/gas/plasma][MOLES]+cached_gases[/datum/gas/tritium][MOLES])
+ var/moles_impurities = max(air.total_moles()-(cached_gases[/datum/gas/plasma][MOLES]+cached_gases[/datum/gas/tritium][MOLES]),1) //This makes it assume a minimum of 1 mol impurities so the reaction energy doesn't divide by 0
- var/plasma_fused = (PLASMA_FUSED_COEFFICENT*catalyst_efficency)*(temperature/PLASMA_BINDING_ENERGY)/10
- var/tritium_catalyzed = (CATALYST_COEFFICENT*catalyst_efficency)*(temperature/PLASMA_BINDING_ENERGY)/40
+ var/plasma_fused = min((PLASMA_FUSED_COEFFICENT*catalyst_efficency)*(temperature/PLASMA_BINDING_ENERGY)/10,cached_gases[/datum/gas/plasma][MOLES]) //Preserve matter
+ var/tritium_catalyzed = min((CATALYST_COEFFICENT*catalyst_efficency)*(temperature/PLASMA_BINDING_ENERGY)/40,cached_gases[/datum/gas/tritium][MOLES]) //Ditto
var/oxygen_added = tritium_catalyzed
var/waste_added = max((plasma_fused-oxygen_added)-((air.total_moles()*air.heat_capacity())/PLASMA_BINDING_ENERGY),0)
- reaction_energy = max(reaction_energy+((catalyst_efficency*cached_gases[/datum/gas/plasma][MOLES])/((moles_impurities/catalyst_efficency)+2)*10)+((plasma_fused/((moles_impurities/catalyst_efficency)))*PLASMA_BINDING_ENERGY),0)
+ reaction_energy = max(reaction_energy+((catalyst_efficency*cached_gases[/datum/gas/plasma][MOLES])/((moles_impurities/catalyst_efficency)+2)*10)+((plasma_fused/(moles_impurities/catalyst_efficency))*PLASMA_BINDING_ENERGY),0)
air.assert_gases(/datum/gas/oxygen, /datum/gas/carbon_dioxide, /datum/gas/water_vapor, /datum/gas/nitrous_oxide, /datum/gas/nitryl)
//Fusion produces an absurd amount of waste products now, requiring active filtration.
@@ -251,7 +252,7 @@
var/temperature = air.temperature
var/old_heat_capacity = air.heat_capacity()
- var/heat_efficency = temperature/(FIRE_MINIMUM_TEMPERATURE_TO_EXIST*100)
+ var/heat_efficency = min(temperature/(FIRE_MINIMUM_TEMPERATURE_TO_EXIST*100),cached_gases[/datum/gas/oxygen][MOLES],cached_gases[/datum/gas/nitrogen][MOLES])
var/energy_used = heat_efficency*NITRYL_FORMATION_ENERGY
ASSERT_GAS(/datum/gas/nitryl,air)
@@ -283,7 +284,7 @@
var/pressure = air.return_pressure()
var/old_heat_capacity = air.heat_capacity()
- var/reaction_efficency = 1/((pressure/(0.1*ONE_ATMOSPHERE))*(max(cached_gases[/datum/gas/plasma][MOLES]/cached_gases[/datum/gas/tritium][MOLES],1)))
+ var/reaction_efficency = min(1/((pressure/(0.1*ONE_ATMOSPHERE))*(max(cached_gases[/datum/gas/plasma][MOLES]/cached_gases[/datum/gas/tritium][MOLES],1))),cached_gases[/datum/gas/tritium][MOLES],cached_gases[/datum/gas/plasma][MOLES]/2)
var/energy_released = 2*reaction_efficency*FIRE_CARBON_ENERGY_RELEASED
ASSERT_GAS(/datum/gas/bz,air)
@@ -314,9 +315,8 @@
var/list/cached_gases = air.gases
var/old_heat_capacity = air.heat_capacity()
- var/heat_scale = air.temperature/STIMULUM_HEAT_SCALE
- var/stim_energy_change
- stim_energy_change =heat_scale + (STIMULUM_FIRST_RISE(heat_scale**2)) - (STIMULUM_FIRST_DROP(heat_scale**3)) + (STIMULUM_SECOND_RISE(heat_scale**4)) - (STIMULUM_ABSOLUTE_DROP(heat_scale**5))
+ var/heat_scale = min(air.temperature/STIMULUM_HEAT_SCALE,cached_gases[/datum/gas/tritium][MOLES],cached_gases[/datum/gas/plasma][MOLES],cached_gases[/datum/gas/nitryl][MOLES])
+ var/stim_energy_change = heat_scale + STIMULUM_FIRST_RISE*(heat_scale**2) - STIMULUM_FIRST_DROP*(heat_scale**3) + STIMULUM_SECOND_RISE*(heat_scale**4) - STIMULUM_ABSOLUTE_DROP*(heat_scale**5)
ASSERT_GAS(/datum/gas/stimulum,air)
cached_gases[/datum/gas/stimulum][MOLES]+= heat_scale/10
@@ -345,7 +345,7 @@
var/list/cached_gases = air.gases
air.assert_gases(/datum/gas/hypernoblium,/datum/gas/bz)
var/old_heat_capacity = air.heat_capacity()
- var/nob_formed = (cached_gases[/datum/gas/nitrogen][MOLES]*cached_gases[/datum/gas/tritium][MOLES])/100
+ var/nob_formed = min((cached_gases[/datum/gas/nitrogen][MOLES]+cached_gases[/datum/gas/tritium][MOLES])/100,cached_gases[/datum/gas/tritium][MOLES]/10,cached_gases[/datum/gas/nitrogen][MOLES]/20)
var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(cached_gases[/datum/gas/bz][MOLES],1)))
cached_gases[/datum/gas/tritium][MOLES] = max(cached_gases[/datum/gas/tritium][MOLES]- 10*nob_formed,0)
cached_gases[/datum/gas/nitrogen][MOLES] = max(cached_gases[/datum/gas/nitrogen][MOLES]- 20*nob_formed,0)
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
index 2a59e14121..df76a47b82 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
@@ -184,7 +184,8 @@
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents.
beaker.reagents.reaction(occupant, VAPOR)
- air1.gases[/datum/gas/oxygen][MOLES] -= 2 / efficiency //Let's use gas for this
+ air1.gases[/datum/gas/oxygen][MOLES] -= max(0,air1.gases[/datum/gas/oxygen][MOLES] - 2 / efficiency) //Let's use gas for this
+ air1.garbage_collect()
if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker).
reagent_transfer = 0
@@ -220,7 +221,8 @@
air1.temperature = max(air1.temperature - heat / air_heat_capacity, TCMB)
mob_occupant.bodytemperature = max(mob_occupant.bodytemperature + heat / heat_capacity, TCMB)
- air1.gases[/datum/gas/oxygen][MOLES] -= 0.5 / efficiency // Magically consume gas? Why not, we run on cryo magic.
+ air1.gases[/datum/gas/oxygen][MOLES] = max(0,air1.gases[/datum/gas/oxygen][MOLES] - 0.5 / efficiency) // Magically consume gas? Why not, we run on cryo magic.
+ air1.garbage_collect()
/obj/machinery/atmospherics/components/unary/cryo_cell/power_change()
..()
diff --git a/code/modules/mob/living/brain/posibrain.dm b/code/modules/mob/living/brain/posibrain.dm
index 33a274c762..b49f8a2570 100644
--- a/code/modules/mob/living/brain/posibrain.dm
+++ b/code/modules/mob/living/brain/posibrain.dm
@@ -64,6 +64,7 @@ GLOBAL_VAR(posibrain_notify_cooldown)
return
if(brainmob.client)
visible_message(success_message)
+ playsound(src, 'sound/machines/ping.ogg', 15, TRUE)
else
visible_message(fail_message)
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 3f15b7a6ad..f4822a066e 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -1622,8 +1622,6 @@ GLOBAL_LIST_EMPTY(roundstart_races)
//Body temperature is adjusted in two parts: first there your body tries to naturally preserve homeostasis (shivering/sweating), then it reacts to the surrounding environment
//Thermal protection (insulation) has mixed benefits in two situations (hot in hot places, cold in hot places)
if(!H.on_fire) //If you're on fire, you do not heat up or cool down based on surrounding gases
- if((abs(BODYTEMP_NORMAL - H.bodytemperature) <= 5) && (abs(BODYTEMP_NORMAL - loc_temp) <= 25))
- return //Performance saver
var/natural = 0
if(H.stat != DEAD)
natural = H.natural_bodytemperature_stabilization()
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 9716ee135d..9301e3b409 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -865,6 +865,8 @@
to_chat(G, "Your summoner has changed form!")
/mob/living/rad_act(amount)
+ . = ..()
+
if(!amount || amount < RAD_MOB_SKIN_PROTECTION)
return
diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm
index bb057f7774..cc17d8e4bd 100644
--- a/code/modules/mob/living/silicon/pai/software.dm
+++ b/code/modules/mob/living/silicon/pai/software.dm
@@ -235,7 +235,8 @@
if(href_list["toggle"])
secHUD = !secHUD
if(secHUD)
- add_sec_hud()
+ var/datum/atom_hud/sec = GLOB.huds[sec_hud]
+ sec.add_hud_to(src)
else
var/datum/atom_hud/sec = GLOB.huds[sec_hud]
sec.remove_hud_from(src)
@@ -243,8 +244,8 @@
if(href_list["toggle"])
medHUD = !medHUD
if(medHUD)
- add_med_hud()
-
+ var/datum/atom_hud/med = GLOB.huds[med_hud]
+ med.add_hud_to(src)
else
var/datum/atom_hud/med = GLOB.huds[med_hud]
med.remove_hud_from(src)
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 5ed5bf5eb0..7df4c9fda0 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -30,6 +30,7 @@
var/ioncheck[1]
var/devillawcheck[5]
+ var/sensors_on = 0
var/med_hud = DATA_HUD_MEDICAL_ADVANCED //Determines the med hud to use
var/sec_hud = DATA_HUD_SECURITY_ADVANCED //Determines the sec hud to use
var/d_hud = DATA_HUD_DIAGNOSTIC_BASIC //Determines the diag hud to use
@@ -328,7 +329,7 @@
/mob/living/silicon/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null) //Secbots won't hunt silicon units
return -10
-/mob/living/silicon/proc/remove_med_sec_hud()
+/mob/living/silicon/proc/remove_sensors()
var/datum/atom_hud/secsensor = GLOB.huds[sec_hud]
var/datum/atom_hud/medsensor = GLOB.huds[med_hud]
var/datum/atom_hud/diagsensor = GLOB.huds[d_hud]
@@ -336,36 +337,24 @@
medsensor.remove_hud_from(src)
diagsensor.remove_hud_from(src)
-/mob/living/silicon/proc/add_sec_hud()
+/mob/living/silicon/proc/add_sensors()
var/datum/atom_hud/secsensor = GLOB.huds[sec_hud]
- secsensor.add_hud_to(src)
-
-/mob/living/silicon/proc/add_med_hud()
var/datum/atom_hud/medsensor = GLOB.huds[med_hud]
- medsensor.add_hud_to(src)
-
-/mob/living/silicon/proc/add_diag_hud()
var/datum/atom_hud/diagsensor = GLOB.huds[d_hud]
+ secsensor.add_hud_to(src)
+ medsensor.add_hud_to(src)
diagsensor.add_hud_to(src)
-/mob/living/silicon/proc/sensor_mode()
+/mob/living/silicon/proc/toggle_sensors()
if(incapacitated())
return
- var/sensor_type = input("Please select sensor type.", "Sensor Integration", null) in list("Security", "Medical","Diagnostic","Disable")
- remove_med_sec_hud()
- switch(sensor_type)
- if ("Security")
- add_sec_hud()
- to_chat(src, "Security records overlay enabled.")
- if ("Medical")
- add_med_hud()
- to_chat(src, "Life signs monitor overlay enabled.")
- if ("Diagnostic")
- add_diag_hud()
- to_chat(src, "Robotics diagnostic overlay enabled.")
- if ("Disable")
- to_chat(src, "Sensor augmentations disabled.")
-
+ sensors_on = !sensors_on
+ if (!sensors_on)
+ to_chat(src, "Sensor overlay deactivated.")
+ remove_sensors()
+ return
+ add_sensors()
+ to_chat(src, "Sensor overlay activated.")
/mob/living/silicon/proc/GetPhoto()
if (aicamera)
diff --git a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm
index 54ef51ad5a..c2595279ff 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm
@@ -33,10 +33,10 @@
/mob/living/simple_animal/hostile/guardian/bomb/AltClickOn(atom/movable/A)
if(!istype(A))
return
- if(src.loc == summoner)
+ if(loc == summoner)
to_chat(src, "You must be manifested to create bombs!")
return
- if(isobj(A))
+ if(isobj(A) && Adjacent(A))
if(bomb_cooldown <= world.time && !stat)
var/obj/guardian_bomb/B = new /obj/guardian_bomb(get_turf(A))
to_chat(src, "Success! Bomb armed!")
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
index 5cb5bbe165..57dda3b39c 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
@@ -226,7 +226,7 @@
max_mobs = 3
spawn_time = 200
spawn_text = "peels itself off from"
- mob_type = /mob/living/simple_animal/hostile/asteroid/hivelord/legion
+ mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion)
melee_damage_lower = 20
melee_damage_upper = 20
anchored = FALSE
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm
index 118f0e1e69..6a7af7910e 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm
@@ -17,7 +17,7 @@
maxHealth = 250
max_mobs = 3
spawn_time = 300 //30 seconds default
- mob_type = /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril
+ mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril)
spawn_text = "emerges from"
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
@@ -28,10 +28,10 @@
var/obj/effect/light_emitter/tendril/emitted_light
/mob/living/simple_animal/hostile/spawner/lavaland/goliath
- mob_type = /mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril
+ mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril)
/mob/living/simple_animal/hostile/spawner/lavaland/legion
- mob_type = /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril
+ mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril)
/mob/living/simple_animal/hostile/spawner/lavaland/Initialize()
. = ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
index 67a565f945..79503d3235 100644
--- a/code/modules/mob/living/simple_animal/hostile/netherworld.dm
+++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
@@ -71,11 +71,11 @@
icon_living = "nether"
health = 50
maxHealth = 50
- spawn_time = 50 //5 seconds
+ spawn_time = 600 //1 minute
max_mobs = 15
icon = 'icons/mob/nest.dmi'
spawn_text = "crawls through"
- mob_type = /mob/living/simple_animal/hostile/netherworld/migo
+ mob_types = list(/mob/living/simple_animal/hostile/netherworld/migo, /mob/living/simple_animal/hostile/netherworld, /mob/living/simple_animal/hostile/netherworld/blankbody)
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
faction = list("nether")
deathmessage = "shatters into oblivion."
@@ -93,7 +93,7 @@
if(M)
playsound(src, 'sound/magic/demon_consume.ogg', 50, 1)
M.adjustBruteLoss(60)
- new /obj/effect/gibspawner/human(get_turf(M))
+ new /obj/effect/gibspawner/generic(get_turf(M))
if(M.stat == DEAD)
var/mob/living/simple_animal/hostile/netherworld/blankbody/blank
blank = new(loc)
diff --git a/code/modules/mob/living/simple_animal/spawner.dm b/code/modules/mob/living/simple_animal/spawner.dm
index a6970ece68..2d3fce3e0b 100644
--- a/code/modules/mob/living/simple_animal/spawner.dm
+++ b/code/modules/mob/living/simple_animal/spawner.dm
@@ -8,7 +8,7 @@
var/max_mobs = 5
var/spawn_delay = 0
var/spawn_time = 300 //30 seconds default
- var/mob_type = /mob/living/simple_animal/hostile/carp
+ var/mob_types = list(/mob/living/simple_animal/hostile/carp)
var/spawn_text = "emerges from"
status_flags = 0
anchored = TRUE
@@ -42,7 +42,8 @@
if(spawn_delay > world.time)
return 0
spawn_delay = world.time + spawn_time
- var/mob/living/simple_animal/L = new mob_type(src.loc)
+ var/chosen_mob_type = pick(mob_types)
+ var/mob/living/simple_animal/L = new chosen_mob_type(src.loc)
L.admin_spawned = admin_spawned //If we were admin spawned, lets have our children count as that as well.
spawned_mobs += L
L.nest = src
@@ -54,7 +55,7 @@
icon = 'icons/obj/device.dmi'
icon_state = "syndbeacon"
spawn_text = "warps in from"
- mob_type = /mob/living/simple_animal/hostile/syndicate/ranged
+ mob_types = list(/mob/living/simple_animal/hostile/syndicate/ranged)
faction = list(ROLE_SYNDICATE)
/mob/living/simple_animal/hostile/spawner/skeleton
@@ -67,7 +68,7 @@
maxHealth = 150
max_mobs = 15
spawn_time = 150
- mob_type = /mob/living/simple_animal/hostile/skeleton
+ mob_types = list(/mob/living/simple_animal/hostile/skeleton)
spawn_text = "climbs out of"
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
faction = list("skeleton")
@@ -82,26 +83,31 @@
max_mobs = 3
icon = 'icons/mob/nest.dmi'
spawn_text = "crawls out of"
- mob_type = /mob/living/simple_animal/hostile/asteroid/goldgrub
+ mob_types = list(/mob/living/simple_animal/hostile/asteroid/goldgrub, /mob/living/simple_animal/hostile/asteroid/goliath, /mob/living/simple_animal/hostile/asteroid/hivelord, /mob/living/simple_animal/hostile/asteroid/basilisk, /mob/living/simple_animal/hostile/asteroid/fugu)
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
faction = list("mining")
+/mob/living/simple_animal/hostile/spawner/mining/goldgrub
+ name = "goldgrub den"
+ desc = "A den housing a nest of goldgrubs, annoying but arguably much better than anything else you'll find in a nest."
+ mob_types = list(/mob/living/simple_animal/hostile/asteroid/goldgrub)
+
/mob/living/simple_animal/hostile/spawner/mining/goliath
name = "goliath den"
desc = "A den housing a nest of goliaths, oh god why?"
- mob_type = /mob/living/simple_animal/hostile/asteroid/goliath
+ mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath)
/mob/living/simple_animal/hostile/spawner/mining/hivelord
name = "hivelord den"
desc = "A den housing a nest of hivelords."
- mob_type = /mob/living/simple_animal/hostile/asteroid/hivelord
+ mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord)
/mob/living/simple_animal/hostile/spawner/mining/basilisk
name = "basilisk den"
desc = "A den housing a nest of basilisks, bring a coat."
- mob_type = /mob/living/simple_animal/hostile/asteroid/basilisk
+ mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk)
/mob/living/simple_animal/hostile/spawner/mining/wumborian
name = "wumborian fugu den"
desc = "A den housing a nest of wumborian fugus, how do they all even fit in there?"
- mob_type = /mob/living/simple_animal/hostile/asteroid/fugu
+ mob_types = list(/mob/living/simple_animal/hostile/asteroid/fugu)
diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm
index 78dba1b3a7..14aad9c7b7 100644
--- a/code/modules/paperwork/photography.dm
+++ b/code/modules/paperwork/photography.dm
@@ -131,6 +131,7 @@
var/blueprints = 0 //are blueprints visible in the current photo being created?
var/list/aipictures = list() //Allows for storage of pictures taken by AI, in a similar manner the datacore stores info. Keeping this here allows us to share some procs w/ regualar camera
var/see_ghosts = 0 //for the spoop of it
+ var/obj/item/disk/holodisk/disk
/obj/item/device/camera/CheckParts(list/parts_list)
@@ -189,8 +190,24 @@
qdel(I)
pictures_left = pictures_max
return
+ if(istype(I, /obj/item/disk/holodisk))
+ if (!disk)
+ if(!user.transferItemToLoc(I, src))
+ to_chat(user, "[I] is stuck to your hand!")
+ return TRUE
+ to_chat(user, "You slide [I] into the back of [src].")
+ disk = I
+ else
+ to_chat(user, "There's already a disk inside [src].")
+ return TRUE //no afterattack
..()
+/obj/item/device/camera/attack_self(mob/user)
+ if(!disk)
+ return
+ to_chat(user, "You eject [disk] out the back of [src].")
+ user.put_in_hands(disk)
+ disk = null
/obj/item/device/camera/examine(mob/user)
..()
@@ -437,13 +454,24 @@
/obj/item/device/camera/afterattack(atom/target, mob/user, flag)
if(!on || !pictures_left || !isturf(target.loc))
return
+ if (disk)
+ if(ismob(target))
+ if (disk.record)
+ QDEL_NULL(disk.record)
- captureimage(target, user, flag)
+ disk.record = new
+ var/mob/M = target
+ disk.record.caller_name = M.name
+ disk.record.set_caller_image(M)
+ else
+ return
+ else
+ captureimage(target, user, flag)
+ pictures_left--
+ to_chat(user, "[pictures_left] photos left.")
playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 75, 1, -3)
- pictures_left--
- to_chat(user, "[pictures_left] photos left.")
icon_state = "camera_off"
on = FALSE
addtimer(CALLBACK(src, .proc/cooldown), 64)
diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm
index 8523ab9f43..f587e578d9 100644
--- a/code/modules/power/singularity/collector.dm
+++ b/code/modules/power/singularity/collector.dm
@@ -44,7 +44,7 @@
playsound(src, 'sound/machines/ding.ogg', 50, 1)
eject()
else
- var/gasdrained = powerproduction_drain*drainratio
+ var/gasdrained = min(powerproduction_drain*drainratio,loaded_tank.air_contents.gases[/datum/gas/plasma][MOLES])
loaded_tank.air_contents.gases[/datum/gas/plasma][MOLES] -= gasdrained
loaded_tank.air_contents.assert_gas(/datum/gas/tritium)
loaded_tank.air_contents.gases[/datum/gas/tritium][MOLES] += gasdrained
@@ -189,6 +189,7 @@
update_icons()
/obj/machinery/power/rad_collector/rad_act(pulse_strength)
+ . = ..()
if(loaded_tank && active && pulse_strength > RAD_COLLECTOR_EFFICIENCY)
last_power += (pulse_strength-RAD_COLLECTOR_EFFICIENCY)*RAD_COLLECTOR_COEFFICIENT
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 4988ed339e..8a1d34ddae 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -1104,6 +1104,7 @@
id = "fungalspores"
description = "Active fungal spores."
color = "#92D17D" // rgb: 146, 209, 125
+ can_synth = FALSE
taste_description = "slime"
/datum/reagent/fungalspores/reaction_mob(mob/M, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0)
diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm
index 42f5adfeca..f49b041b49 100644
--- a/code/modules/surgery/organs/lungs.dm
+++ b/code/modules/surgery/organs/lungs.dm
@@ -282,7 +282,6 @@
H.reagents.add_reagent("nitryl_gas",1)
breath_gases[/datum/gas/nitryl][MOLES]-=gas_breathed
- gas_breathed = 0
// Stimulum
gas_breathed = breath_gases[/datum/gas/stimulum][MOLES]
if (gas_breathed > gas_stimulation_min)
diff --git a/html/changelogs/AutoChangeLog-pr-5342.yml b/html/changelogs/AutoChangeLog-pr-5342.yml
new file mode 100644
index 0000000000..0f574fa287
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-5342.yml
@@ -0,0 +1,11 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - bugfix: "Fixes Noblium Formation being multiplicative, so having 500 moles of tritium and 500 moles of nitrogen no longer produces 2500 moles of noblium (it should correctly produce 10 moles)"
+ - bugfix: "Fixes most reactions deleting more gas than exists and making gas out of nowhere"
+ - bugfix: "Fixes Stim Formation invoking a byond bug and not using its intended polynomial formula"
+ - bugfix: "Fixes Cryo Cells not having garbage_collect and clamping"
+ - bugfix: "Fixes Rad Collectors not having clamping"
+ - bugfix: "Fixes Division by Zero when Fusion has no impurities."
+ - bugfix: "Removes a redundant line in lungs"
+ - bugfix: "Fixes rad_act signal not firing from turfs, living mobs, rad collectors and geiger counters"
diff --git a/html/changelogs/AutoChangeLog-pr-5343.yml b/html/changelogs/AutoChangeLog-pr-5343.yml
new file mode 100644
index 0000000000..c98d65651d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-5343.yml
@@ -0,0 +1,5 @@
+author: "Robustin"
+delete-after: True
+changes:
+ - balance: "The \"construct shell\" option from the cult archives structure will now only yield one shell instead of two."
+ - balance: "Sacrificing suicide victims will now only yield an empty shard."
diff --git a/html/changelogs/AutoChangeLog-pr-5344.yml b/html/changelogs/AutoChangeLog-pr-5344.yml
new file mode 100644
index 0000000000..ef79f1f8db
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-5344.yml
@@ -0,0 +1,4 @@
+author: "Xhuis"
+delete-after: True
+changes:
+ - tweak: "Brass chairs now stop spinning after eight rotations, so you can't crash the server with them."
diff --git a/html/changelogs/AutoChangeLog-pr-5346.yml b/html/changelogs/AutoChangeLog-pr-5346.yml
new file mode 100644
index 0000000000..903c84baa9
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-5346.yml
@@ -0,0 +1,4 @@
+author: "Dax Dupont"
+delete-after: True
+changes:
+ - rscadd: "Posibrains have gotten a small firmware update, they will now play a sound on successful activation."
diff --git a/html/changelogs/AutoChangeLog-pr-5347.yml b/html/changelogs/AutoChangeLog-pr-5347.yml
new file mode 100644
index 0000000000..defe872622
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-5347.yml
@@ -0,0 +1,4 @@
+author: "Robustin"
+delete-after: True
+changes:
+ - balance: "Synths and Androids are no longer available species at the magic mirror."
diff --git a/html/changelogs/AutoChangeLog-pr-5349.yml b/html/changelogs/AutoChangeLog-pr-5349.yml
new file mode 100644
index 0000000000..50410e7a5a
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-5349.yml
@@ -0,0 +1,4 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - bugfix: "Pressure damage now takes effect in certain situations where it should have but did not."
diff --git a/html/changelogs/AutoChangeLog-pr-5350.yml b/html/changelogs/AutoChangeLog-pr-5350.yml
new file mode 100644
index 0000000000..83434410b4
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-5350.yml
@@ -0,0 +1,4 @@
+author: "Denton"
+delete-after: True
+changes:
+ - tweak: "Fungal tuberculosis spores can no longer be synthesized by machinery."
diff --git a/html/changelogs/AutoChangeLog-pr-5351.yml b/html/changelogs/AutoChangeLog-pr-5351.yml
new file mode 100644
index 0000000000..9274bacdc7
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-5351.yml
@@ -0,0 +1,5 @@
+author: "Dax Dupont"
+delete-after: True
+changes:
+ - rscadd: "You can now insert holodisks into cameras and take a static holographic picture of someone!"
+ - rscadd: "Hologram recordings can now be offset slightly."
diff --git a/html/changelogs/AutoChangeLog-pr-5353.yml b/html/changelogs/AutoChangeLog-pr-5353.yml
new file mode 100644
index 0000000000..18cabc4544
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-5353.yml
@@ -0,0 +1,4 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - balance: "Explosive holoparasites must now be adjacent to turn objects into bombs, instead of being able to do so from any range."
diff --git a/html/changelogs/AutoChangeLog-pr-5354.yml b/html/changelogs/AutoChangeLog-pr-5354.yml
new file mode 100644
index 0000000000..979dafc239
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-5354.yml
@@ -0,0 +1,5 @@
+author: "Dax Dupont"
+delete-after: True
+changes:
+ - rscadd: "Killing a revenant will now result in an unique shuttle to be able to be bought. You probably won't like it though."
+ - rscadd: "Fake emag now available."