diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk1.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk1.dmm
index 589f1c194a4..5629bb19b49 100644
--- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk1.dmm
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk1.dmm
@@ -151,10 +151,6 @@
/obj/structure/stone_tile/cracked,
/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
-"z" = (
-/obj/effect/baseturf_helper/lava_land/surface,
-/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
-/area/lavaland/surface/outdoors)
(1,1,1) = {"
a
@@ -291,7 +287,7 @@ f
j
c
r
-z
+c
o
c
c
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk2.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk2.dmm
index 121d949e34d..3d224a617d6 100644
--- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk2.dmm
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk2.dmm
@@ -121,16 +121,6 @@
},
/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
-"u" = (
-/obj/structure/stone_tile{
- dir = 8
- },
-/obj/structure/stone_tile{
- dir = 1
- },
-/obj/effect/baseturf_helper/lava_land/surface,
-/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
-/area/lavaland/surface/outdoors)
"v" = (
/obj/structure/stone_tile/block/cracked,
/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
@@ -261,7 +251,7 @@ f
f
o
r
-u
+q
w
f
f
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk3.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk3.dmm
index d14383a82dc..0f6c96fb041 100644
--- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk3.dmm
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk3.dmm
@@ -57,16 +57,6 @@
/obj/structure/stone_tile/cracked,
/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
-"j" = (
-/obj/structure/stone_tile/block{
- dir = 8
- },
-/obj/structure/stone_tile/block/cracked{
- dir = 4
- },
-/obj/effect/baseturf_helper/lava_land/surface,
-/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
-/area/lavaland/surface/outdoors)
"k" = (
/obj/structure/stone_tile,
/obj/structure/stone_tile{
@@ -274,7 +264,7 @@ d
f
d
f
-j
+e
d
w
f
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_cube.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_cube.dmm
new file mode 100644
index 00000000000..888ead3e24c
--- /dev/null
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_cube.dmm
@@ -0,0 +1,980 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/simulated/mineral/volcanic/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"b" = (
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"c" = (
+/obj/effect/decal/remains/human,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"d" = (
+/turf/unsimulated/wall,
+/area/lavaland/surface/outdoors)
+"e" = (
+/obj/machinery/wish_granter,
+/obj/effect/mapping_helpers/no_lava,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+
+(1,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+a
+b
+b
+b
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+b
+a
+"}
+(2,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+a
+b
+b
+c
+b
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(3,1,1) = {"
+a
+b
+a
+a
+a
+a
+b
+a
+a
+a
+a
+a
+a
+a
+b
+a
+b
+b
+b
+a
+a
+b
+b
+a
+a
+b
+b
+a
+a
+a
+"}
+(4,1,1) = {"
+a
+a
+a
+a
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+b
+b
+b
+a
+a
+b
+b
+b
+b
+b
+b
+b
+b
+a
+b
+b
+"}
+(5,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+a
+a
+b
+"}
+(6,1,1) = {"
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+a
+b
+"}
+(7,1,1) = {"
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+b
+b
+b
+b
+b
+c
+b
+b
+c
+b
+b
+b
+c
+b
+b
+b
+b
+a
+"}
+(8,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+a
+"}
+(9,1,1) = {"
+a
+a
+b
+a
+a
+a
+a
+a
+a
+a
+b
+b
+b
+b
+c
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+"}
+(10,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+b
+b
+b
+c
+b
+b
+b
+b
+b
+b
+b
+b
+c
+b
+b
+b
+"}
+(11,1,1) = {"
+a
+a
+a
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+c
+b
+b
+b
+b
+b
+b
+"}
+(12,1,1) = {"
+a
+a
+b
+a
+a
+a
+b
+b
+a
+a
+c
+b
+b
+b
+b
+b
+c
+b
+c
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+"}
+(13,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+c
+c
+b
+c
+c
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+c
+b
+"}
+(14,1,1) = {"
+a
+a
+b
+c
+b
+b
+b
+b
+c
+b
+c
+d
+d
+d
+d
+d
+b
+b
+b
+b
+b
+b
+c
+b
+b
+b
+b
+b
+b
+b
+"}
+(15,1,1) = {"
+a
+a
+b
+b
+b
+b
+c
+b
+b
+b
+b
+d
+d
+d
+d
+d
+b
+c
+b
+b
+c
+b
+a
+b
+b
+b
+b
+b
+b
+b
+"}
+(16,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+b
+c
+b
+d
+d
+e
+d
+d
+b
+b
+a
+a
+b
+b
+a
+a
+b
+b
+b
+b
+b
+b
+"}
+(17,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+c
+b
+b
+c
+d
+d
+d
+d
+d
+c
+c
+a
+a
+a
+a
+a
+a
+a
+b
+b
+a
+b
+b
+"}
+(18,1,1) = {"
+a
+a
+b
+a
+a
+a
+b
+b
+b
+b
+b
+d
+d
+d
+d
+d
+b
+c
+b
+a
+a
+a
+a
+a
+b
+b
+b
+c
+a
+a
+"}
+(19,1,1) = {"
+a
+a
+b
+a
+a
+a
+b
+b
+b
+b
+b
+c
+b
+c
+c
+b
+c
+b
+b
+a
+a
+a
+a
+a
+b
+a
+b
+b
+a
+a
+"}
+(20,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+c
+b
+b
+b
+c
+b
+b
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(21,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+c
+b
+b
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(22,1,1) = {"
+a
+a
+b
+b
+b
+b
+a
+b
+b
+b
+a
+b
+b
+b
+b
+b
+b
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(23,1,1) = {"
+a
+a
+a
+a
+a
+a
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+c
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(24,1,1) = {"
+a
+a
+a
+a
+a
+a
+c
+b
+b
+b
+b
+b
+b
+b
+c
+b
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(25,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(26,1,1) = {"
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+c
+b
+b
+b
+b
+b
+a
+a
+a
+a
+a
+b
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(27,1,1) = {"
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+b
+c
+b
+b
+a
+b
+b
+b
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(28,1,1) = {"
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+c
+b
+b
+b
+b
+b
+b
+b
+"}
+(29,1,1) = {"
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+b
+b
+b
+b
+b
+b
+b
+a
+a
+a
+a
+b
+a
+b
+b
+b
+b
+"}
+(30,1,1) = {"
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm
new file mode 100644
index 00000000000..d9d2feef160
--- /dev/null
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm
@@ -0,0 +1,367 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/template_noop)
+"b" = (
+/turf/simulated/floor/engine/cult{
+ oxygen = 24;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"c" = (
+/turf/simulated/floor/plating/lava/smooth/lava_land_surface,
+/area/ruin/unpowered)
+"d" = (
+/turf/simulated/wall/cult,
+/area/ruin/unpowered)
+"e" = (
+/obj/effect/decal/remains/human,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered)
+"f" = (
+/obj/structure/cult/pylon,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered)
+"g" = (
+/obj/effect/decal/cleanable/blood/old,
+/turf/simulated/floor/engine/cult{
+ oxygen = 24;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"h" = (
+/obj/effect/baseturf_helper/lava_land/surface,
+/turf/simulated/wall/cult,
+/area/ruin/unpowered)
+"i" = (
+/obj/effect/decal/remains/human,
+/obj/effect/decal/cleanable/blood/old,
+/turf/simulated/floor/engine/cult{
+ oxygen = 24;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"k" = (
+/obj/effect/decal/remains/human,
+/obj/item/melee/cultblade,
+/turf/simulated/floor/engine/cult{
+ oxygen = 24;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"l" = (
+/obj/effect/decal/remains/human,
+/obj/item/clothing/shoes/cult,
+/obj/item/clothing/suit/hooded/cultrobes,
+/turf/simulated/floor/engine/cult{
+ oxygen = 24;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"m" = (
+/obj/effect/decal/remains/human,
+/turf/simulated/floor/engine/cult{
+ oxygen = 24;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"o" = (
+/obj/effect/rune/narsie{
+ color = "#ff0000";
+ used = 1
+ },
+/obj/item/cult_shift,
+/obj/effect/decal/remains/human,
+/obj/item/melee/cultblade/dagger,
+/obj/effect/step_trigger/sound_effect{
+ happens_once = 1;
+ name = "a grave mistake";
+ sound = 'sound/hallucinations/i_see_you1.ogg';
+ triggerer_only = 1
+ },
+/obj/effect/step_trigger/message{
+ message = "You've made a grave mistake, haven't you?";
+ name = "ohfuck"
+ },
+/turf/simulated/floor/engine/cult{
+ oxygen = 24;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"q" = (
+/obj/effect/decal/remains/human,
+/obj/item/clothing/shoes/cult,
+/obj/item/clothing/suit/hooded/cultrobes,
+/obj/effect/decal/cleanable/blood/old,
+/turf/simulated/floor/engine/cult{
+ oxygen = 24;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"s" = (
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered)
+
+(1,1,1) = {"
+a
+a
+a
+a
+a
+a
+b
+c
+b
+a
+a
+a
+a
+a
+a
+"}
+(2,1,1) = {"
+a
+d
+e
+c
+s
+c
+b
+b
+b
+c
+s
+c
+s
+d
+a
+"}
+(3,1,1) = {"
+a
+e
+f
+s
+d
+c
+c
+g
+c
+c
+d
+e
+f
+s
+a
+"}
+(4,1,1) = {"
+a
+c
+s
+c
+c
+c
+c
+b
+c
+c
+c
+c
+e
+c
+a
+"}
+(5,1,1) = {"
+a
+s
+d
+c
+c
+b
+b
+b
+b
+b
+c
+c
+d
+s
+a
+"}
+(6,1,1) = {"
+a
+c
+c
+c
+b
+b
+l
+d
+k
+b
+b
+c
+c
+c
+a
+"}
+(7,1,1) = {"
+b
+b
+c
+c
+g
+i
+b
+b
+b
+l
+b
+c
+c
+b
+b
+"}
+(8,1,1) = {"
+c
+b
+g
+b
+b
+d
+b
+o
+b
+d
+b
+b
+g
+b
+c
+"}
+(9,1,1) = {"
+b
+b
+c
+c
+b
+k
+b
+b
+b
+m
+b
+c
+c
+b
+b
+"}
+(10,1,1) = {"
+a
+c
+c
+c
+g
+b
+m
+h
+q
+b
+b
+c
+c
+c
+a
+"}
+(11,1,1) = {"
+a
+s
+d
+c
+c
+b
+b
+b
+b
+b
+c
+c
+d
+s
+a
+"}
+(12,1,1) = {"
+a
+c
+s
+c
+c
+c
+c
+b
+c
+c
+c
+c
+e
+c
+a
+"}
+(13,1,1) = {"
+a
+e
+f
+s
+d
+c
+c
+g
+c
+c
+d
+e
+f
+s
+a
+"}
+(14,1,1) = {"
+a
+d
+e
+c
+s
+c
+b
+b
+b
+c
+s
+c
+s
+d
+a
+"}
+(15,1,1) = {"
+a
+a
+a
+a
+a
+a
+b
+c
+b
+a
+a
+a
+a
+a
+a
+"}
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_dead_ratvar.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_dead_ratvar.dmm
new file mode 100644
index 00000000000..03959657af8
--- /dev/null
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_dead_ratvar.dmm
@@ -0,0 +1,1018 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/template_noop)
+"b" = (
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors/unexplored)
+"c" = (
+/obj/item/clockwork/alloy_shards/small,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors/unexplored)
+"d" = (
+/obj/structure/clockwork/wall_gear,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors/unexplored)
+"e" = (
+/obj/item/stack/tile/brass,
+/turf/simulated/floor/clockwork{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/lavaland/surface/outdoors/unexplored)
+"f" = (
+/turf/simulated/mineral/volcanic/lava_land_surface,
+/area/lavaland/surface/outdoors/unexplored)
+"g" = (
+/obj/item/clockwork/alloy_shards/medium/gear_bit,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors/unexplored)
+"h" = (
+/turf/simulated/floor/clockwork{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/lavaland/surface/outdoors/unexplored)
+"i" = (
+/obj/structure/grille/ratvar/broken,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors/unexplored)
+"j" = (
+/turf/simulated/wall/clockwork,
+/area/lavaland/surface/outdoors/unexplored)
+"k" = (
+/obj/item/clockwork/alloy_shards/small,
+/turf/simulated/floor/clockwork{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/lavaland/surface/outdoors/unexplored)
+"l" = (
+/turf/simulated/floor/plating/lava/smooth/lava_land_surface,
+/area/lavaland/surface/outdoors/unexplored)
+"m" = (
+/obj/item/clockwork/alloy_shards/medium,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors/unexplored)
+"n" = (
+/obj/item/clockwork/component/belligerent_eye/blind_eye,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors/unexplored)
+"o" = (
+/obj/item/clockwork/alloy_shards/large,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors/unexplored)
+"p" = (
+/obj/item/clockwork/alloy_shards/medium,
+/turf/simulated/floor/clockwork{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/lavaland/surface/outdoors/unexplored)
+"q" = (
+/obj/structure/lattice/catwalk/clockwork,
+/turf/simulated/floor/plating/lava/smooth/lava_land_surface,
+/area/lavaland/surface/outdoors/unexplored)
+"r" = (
+/obj/structure/lattice/clockwork,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors/unexplored)
+"s" = (
+/obj/item/clockwork/alloy_shards/large,
+/turf/simulated/floor/clockwork{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/lavaland/surface/outdoors/unexplored)
+"t" = (
+/obj/item/stack/tile/brass,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors/unexplored)
+"u" = (
+/obj/structure/grille/ratvar,
+/turf/simulated/floor/clockwork{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/lavaland/surface/outdoors/unexplored)
+"v" = (
+/obj/item/clockwork/alloy_shards/medium,
+/obj/structure/lattice/clockwork,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors/unexplored)
+"w" = (
+/obj/structure/grille/ratvar/broken,
+/turf/simulated/floor/clockwork{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/lavaland/surface/outdoors/unexplored)
+"x" = (
+/obj/structure/clockwork/wall_gear,
+/obj/item/stack/tile/brass,
+/turf/simulated/floor/clockwork{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/lavaland/surface/outdoors/unexplored)
+"y" = (
+/obj/item/clockwork/component/geis_capacitor/fallen_armor,
+/turf/simulated/floor/clockwork{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/lavaland/surface/outdoors/unexplored)
+"z" = (
+/obj/structure/clockwork/wall_gear,
+/turf/simulated/floor/clockwork{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/lavaland/surface/outdoors/unexplored)
+"A" = (
+/obj/item/clockwork/alloy_shards/clockgolem_remains,
+/turf/simulated/floor/clockwork{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/lavaland/surface/outdoors/unexplored)
+"B" = (
+/obj/item/clockwork/weapon/ratvarian_spear,
+/turf/simulated/floor/clockwork{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/lavaland/surface/outdoors/unexplored)
+"C" = (
+/obj/item/clockwork/alloy_shards/medium/gear_bit,
+/turf/simulated/floor/clockwork{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/lavaland/surface/outdoors/unexplored)
+"D" = (
+/obj/structure/grille/ratvar,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors/unexplored)
+"E" = (
+/obj/item/clockwork/alloy_shards/clockgolem_remains,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors/unexplored)
+"F" = (
+/obj/structure/dead_ratvar,
+/turf/simulated/floor/clockwork{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/lavaland/surface/outdoors/unexplored)
+"G" = (
+/obj/item/stack/tile/brass/fifty,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors/unexplored)
+
+(1,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+s
+h
+b
+a
+a
+a
+a
+a
+a
+a
+"}
+(2,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+o
+b
+a
+h
+b
+r
+c
+j
+x
+b
+b
+g
+a
+a
+a
+a
+a
+"}
+(3,1,1) = {"
+a
+a
+a
+a
+a
+a
+f
+b
+l
+b
+v
+b
+p
+w
+j
+j
+c
+l
+b
+b
+a
+a
+a
+a
+"}
+(4,1,1) = {"
+a
+a
+a
+a
+a
+a
+f
+l
+l
+r
+b
+b
+l
+j
+j
+j
+p
+l
+b
+h
+c
+r
+a
+a
+"}
+(5,1,1) = {"
+a
+a
+a
+a
+a
+b
+l
+l
+p
+h
+c
+l
+l
+l
+j
+l
+b
+l
+l
+D
+h
+r
+a
+a
+"}
+(6,1,1) = {"
+a
+a
+a
+h
+c
+h
+m
+l
+l
+c
+l
+l
+l
+l
+w
+l
+l
+l
+m
+c
+h
+f
+a
+a
+"}
+(7,1,1) = {"
+a
+a
+b
+b
+b
+l
+l
+l
+l
+h
+b
+l
+l
+l
+l
+l
+l
+l
+l
+c
+f
+f
+b
+a
+"}
+(8,1,1) = {"
+a
+h
+h
+g
+c
+b
+l
+l
+l
+l
+n
+h
+r
+l
+l
+b
+l
+l
+l
+l
+f
+b
+a
+a
+"}
+(9,1,1) = {"
+a
+b
+c
+b
+b
+l
+l
+l
+l
+t
+h
+b
+h
+w
+p
+b
+g
+l
+l
+b
+b
+b
+b
+a
+"}
+(10,1,1) = {"
+b
+h
+l
+l
+l
+l
+l
+l
+b
+b
+p
+r
+F
+b
+h
+A
+b
+l
+l
+l
+m
+l
+l
+a
+"}
+(11,1,1) = {"
+c
+i
+j
+j
+l
+l
+l
+l
+l
+b
+h
+k
+h
+h
+h
+r
+l
+l
+l
+l
+l
+l
+b
+a
+"}
+(12,1,1) = {"
+d
+j
+j
+j
+h
+l
+l
+b
+l
+q
+r
+h
+h
+h
+c
+q
+l
+b
+l
+l
+b
+h
+o
+a
+"}
+(13,1,1) = {"
+e
+k
+b
+l
+l
+l
+b
+p
+s
+r
+h
+h
+h
+h
+h
+h
+h
+l
+l
+l
+l
+b
+b
+a
+"}
+(14,1,1) = {"
+b
+b
+b
+m
+l
+l
+l
+b
+h
+h
+k
+h
+h
+h
+h
+h
+c
+b
+l
+l
+b
+b
+h
+b
+"}
+(15,1,1) = {"
+b
+b
+b
+l
+l
+l
+l
+h
+h
+h
+h
+h
+h
+h
+k
+B
+h
+l
+l
+l
+l
+b
+b
+a
+"}
+(16,1,1) = {"
+f
+l
+l
+l
+l
+l
+l
+q
+b
+h
+h
+h
+h
+h
+h
+s
+b
+l
+l
+l
+l
+f
+f
+a
+"}
+(17,1,1) = {"
+b
+b
+b
+l
+l
+l
+b
+l
+q
+r
+h
+h
+h
+h
+h
+b
+s
+r
+l
+r
+l
+l
+b
+a
+"}
+(18,1,1) = {"
+b
+h
+l
+l
+l
+b
+b
+h
+b
+h
+h
+h
+h
+h
+r
+k
+b
+C
+r
+h
+b
+b
+m
+b
+"}
+(19,1,1) = {"
+b
+b
+l
+l
+l
+l
+h
+b
+h
+h
+h
+h
+h
+h
+h
+r
+j
+h
+c
+h
+r
+h
+b
+b
+"}
+(20,1,1) = {"
+b
+l
+l
+l
+l
+b
+b
+p
+h
+c
+h
+k
+h
+h
+o
+b
+l
+l
+l
+b
+E
+r
+G
+o
+"}
+(21,1,1) = {"
+g
+b
+l
+l
+l
+l
+l
+r
+h
+r
+h
+h
+h
+h
+y
+l
+l
+l
+l
+l
+l
+j
+j
+r
+"}
+(22,1,1) = {"
+c
+c
+b
+l
+l
+b
+h
+h
+t
+b
+h
+h
+h
+h
+h
+m
+b
+l
+l
+l
+h
+j
+j
+j
+"}
+(23,1,1) = {"
+b
+h
+m
+n
+b
+h
+l
+o
+j
+u
+r
+p
+h
+r
+h
+b
+l
+l
+l
+b
+b
+w
+r
+b
+"}
+(24,1,1) = {"
+a
+a
+b
+b
+l
+l
+l
+j
+j
+q
+p
+h
+m
+e
+z
+j
+j
+l
+l
+c
+l
+l
+b
+a
+"}
+(25,1,1) = {"
+a
+a
+a
+l
+l
+l
+l
+j
+l
+l
+b
+h
+r
+x
+h
+l
+l
+l
+l
+l
+l
+a
+a
+a
+"}
+(26,1,1) = {"
+a
+a
+a
+c
+b
+l
+l
+l
+l
+l
+l
+g
+q
+b
+h
+l
+l
+l
+c
+m
+b
+a
+a
+a
+"}
+(27,1,1) = {"
+a
+a
+a
+b
+h
+b
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+b
+a
+a
+a
+a
+"}
+(28,1,1) = {"
+a
+a
+a
+a
+c
+b
+l
+b
+l
+l
+l
+l
+l
+l
+l
+l
+b
+l
+f
+a
+a
+a
+a
+a
+"}
+(29,1,1) = {"
+a
+a
+a
+a
+b
+b
+f
+c
+b
+l
+c
+l
+l
+l
+l
+c
+o
+l
+b
+a
+a
+a
+a
+a
+"}
+(30,1,1) = {"
+a
+a
+a
+a
+a
+g
+c
+b
+l
+l
+b
+m
+l
+b
+l
+f
+b
+a
+a
+a
+a
+a
+a
+a
+"}
+(31,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+b
+l
+b
+a
+b
+l
+c
+f
+f
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(32,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+c
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_envy.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_envy.dmm
new file mode 100644
index 00000000000..2be9246bcfc
--- /dev/null
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_envy.dmm
@@ -0,0 +1,328 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"b" = (
+/turf/simulated/mineral/volcanic/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"c" = (
+/turf/simulated/floor/plating/lava/smooth/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"d" = (
+/turf/simulated/wall/rust,
+/area/ruin/unpowered)
+"e" = (
+/obj/structure/mirror{
+ desc = "This mirror has been shattered. It looks like the bad luck energies spilling from it are taking immediate effect on your surroundings!";
+ icon_state = "mirror_broke";
+ pixel_x = -28;
+ broken = 1
+ },
+/obj/item/clothing/suit/bloated_human,
+/obj/effect/decal/cleanable/blood,
+/obj/item/clothing/head/human_head,
+/turf/simulated/floor/plating,
+/area/ruin/unpowered)
+"f" = (
+/obj/structure/mirror{
+ desc = "This mirror has been shattered. It looks like the bad luck energies spilling from it are taking immediate effect on your surroundings!";
+ icon_state = "mirror_broke";
+ pixel_x = 28;
+ broken = 1
+ },
+/turf/simulated/floor/plating/burnt,
+/area/ruin/unpowered)
+"g" = (
+/obj/effect/decal/cleanable/blood/tracks,
+/obj/structure/mirror{
+ desc = "This mirror has been shattered. It looks like the bad luck energies spilling from it are taking immediate effect on your surroundings!";
+ icon_state = "mirror_broke";
+ pixel_x = -28;
+ broken = 1
+ },
+/turf/simulated/floor/plating,
+/area/ruin/unpowered)
+"h" = (
+/obj/effect/decal/cleanable/blood,
+/turf/simulated/floor/plating,
+/area/ruin/unpowered)
+"i" = (
+/turf/simulated/floor/plating,
+/area/ruin/unpowered)
+"j" = (
+/obj/effect/decal/cleanable/blood/splatter,
+/turf/simulated/floor/plating,
+/area/ruin/unpowered)
+"k" = (
+/obj/structure/mirror{
+ desc = "This mirror has been shattered. It looks like the bad luck energies spilling from it are taking immediate effect on your surroundings!";
+ icon_state = "mirror_broke";
+ pixel_y = 28;
+ broken = 1
+ },
+/obj/item/kitchen/knife/envy,
+/turf/simulated/floor/plating,
+/area/ruin/unpowered)
+"l" = (
+/obj/structure/mirror{
+ desc = "This mirror has been shattered. It looks like the bad luck energies spilling from it are taking immediate effect on your surroundings!";
+ icon_state = "mirror_broke";
+ pixel_x = 28;
+ broken = 1
+ },
+/turf/simulated/floor/plating,
+/area/ruin/unpowered)
+"m" = (
+/obj/structure/mirror{
+ desc = "This mirror has been shattered. It looks like the bad luck energies spilling from it are taking immediate effect on your surroundings!";
+ icon_state = "mirror_broke";
+ pixel_x = -28;
+ broken = 1
+ },
+/turf/simulated/floor/plating,
+/area/ruin/unpowered)
+"n" = (
+/turf/simulated/floor/plating/damaged,
+/area/ruin/unpowered)
+"o" = (
+/obj/structure/mirror{
+ desc = "This mirror has been shattered. It looks like the bad luck energies spilling from it are taking immediate effect on your surroundings!";
+ icon_state = "mirror_broke";
+ pixel_x = -28;
+ broken = 1
+ },
+/turf/simulated/floor/plating/damaged,
+/area/ruin/unpowered)
+"p" = (
+/obj/machinery/door/airlock/hatch,
+/turf/simulated/floor/plating,
+/area/ruin/unpowered)
+"q" = (
+/obj/effect/baseturf_helper/lava_land/surface,
+/turf/simulated/floor/plating,
+/area/ruin/unpowered)
+"A" = (
+/obj/effect/mapping_helpers/no_lava,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+
+(1,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(2,1,1) = {"
+a
+a
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+a
+"}
+(3,1,1) = {"
+b
+c
+c
+d
+d
+d
+d
+d
+d
+d
+d
+d
+d
+d
+d
+d
+d
+d
+c
+a
+"}
+(4,1,1) = {"
+c
+c
+d
+d
+d
+e
+g
+g
+g
+m
+m
+m
+m
+m
+o
+m
+j
+d
+c
+a
+"}
+(5,1,1) = {"
+c
+d
+d
+d
+d
+d
+h
+h
+i
+i
+i
+i
+i
+h
+i
+i
+i
+d
+A
+a
+"}
+(6,1,1) = {"
+c
+d
+d
+d
+d
+d
+d
+k
+i
+i
+i
+q
+i
+i
+i
+i
+i
+p
+A
+a
+"}
+(7,1,1) = {"
+c
+d
+d
+d
+d
+d
+i
+i
+i
+j
+i
+n
+i
+i
+i
+i
+i
+d
+c
+a
+"}
+(8,1,1) = {"
+c
+c
+d
+d
+d
+f
+j
+l
+l
+l
+l
+l
+l
+l
+l
+l
+j
+d
+c
+a
+"}
+(9,1,1) = {"
+b
+c
+c
+d
+d
+d
+d
+d
+d
+d
+d
+d
+d
+d
+d
+d
+d
+d
+c
+a
+"}
+(10,1,1) = {"
+b
+b
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+a
+"}
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_fountain_hall.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_fountain_hall.dmm
new file mode 100644
index 00000000000..4c793cc1ffa
--- /dev/null
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_fountain_hall.dmm
@@ -0,0 +1,161 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/template_noop)
+"b" = (
+/turf/simulated/wall/cult,
+/area/ruin/unpowered)
+"c" = (
+/obj/structure/healingfountain,
+/turf/simulated/floor/engine/cult,
+/area/ruin/unpowered)
+"d" = (
+/obj/structure/fluff/divine/conduit,
+/turf/simulated/floor/engine/cult,
+/area/ruin/unpowered)
+"e" = (
+/obj/structure/sacrificealtar,
+/turf/simulated/floor/engine/cult,
+/area/ruin/unpowered)
+"f" = (
+/turf/simulated/floor/engine/cult,
+/area/ruin/unpowered)
+"g" = (
+/mob/living/simple_animal/butterfly,
+/turf/simulated/floor/engine/cult,
+/area/ruin/unpowered)
+"h" = (
+/obj/structure/fans/tiny/invisible,
+/turf/simulated/floor/engine/cult,
+/area/ruin/unpowered)
+"i" = (
+/obj/effect/baseturf_helper/lava_land/surface,
+/turf/simulated/floor/engine/cult,
+/area/ruin/unpowered)
+
+(1,1,1) = {"
+a
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+"}
+(2,1,1) = {"
+a
+b
+d
+f
+f
+d
+f
+f
+d
+f
+f
+d
+f
+f
+d
+b
+"}
+(3,1,1) = {"
+b
+b
+e
+g
+f
+f
+g
+f
+f
+f
+f
+g
+f
+g
+f
+b
+"}
+(4,1,1) = {"
+b
+c
+f
+f
+f
+f
+f
+f
+i
+f
+f
+f
+f
+f
+f
+h
+"}
+(5,1,1) = {"
+b
+b
+e
+f
+f
+f
+f
+g
+f
+f
+f
+f
+f
+f
+f
+b
+"}
+(6,1,1) = {"
+a
+b
+d
+g
+f
+d
+f
+f
+d
+f
+f
+d
+f
+g
+d
+b
+"}
+(7,1,1) = {"
+a
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+"}
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_gluttony.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_gluttony.dmm
new file mode 100644
index 00000000000..e449be961cd
--- /dev/null
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_gluttony.dmm
@@ -0,0 +1,539 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/simulated/mineral/volcanic/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"b" = (
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"c" = (
+/turf/simulated/floor/plating/lava/smooth/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"d" = (
+/obj/effect/baseturf_helper/lava_land/surface,
+/turf/simulated/floor/plasteel/freezer,
+/area/ruin/powered/gluttony)
+"e" = (
+/turf/simulated/floor/plating/lava/smooth,
+/area/ruin/powered/gluttony)
+"f" = (
+/obj/item/reagent_containers/syringe/gluttony,
+/turf/simulated/floor/plasteel/freezer,
+/area/ruin/powered/gluttony)
+"g" = (
+/obj/effect/gluttony,
+/turf/simulated/floor/plasteel/freezer,
+/area/ruin/powered/gluttony)
+"h" = (
+/obj/item/veilrender/vealrender,
+/turf/simulated/floor/plasteel/freezer,
+/area/ruin/powered/gluttony)
+"i" = (
+/turf/simulated/floor/plasteel/freezer,
+/area/ruin/powered/gluttony)
+"j" = (
+/obj/item/trash/plate,
+/turf/simulated/floor/plasteel/freezer,
+/area/ruin/powered/gluttony)
+"l" = (
+/obj/item/trash/candy,
+/turf/simulated/floor/plasteel/freezer,
+/area/ruin/powered/gluttony)
+"m" = (
+/obj/item/trash/raisins,
+/turf/simulated/floor/plasteel/freezer,
+/area/ruin/powered/gluttony)
+"n" = (
+/obj/item/trash/pistachios,
+/turf/simulated/floor/plasteel/freezer,
+/area/ruin/powered/gluttony)
+"o" = (
+/obj/item/trash/popcorn,
+/turf/simulated/floor/plasteel/freezer,
+/area/ruin/powered/gluttony)
+"p" = (
+/obj/item/trash/semki,
+/turf/simulated/floor/plasteel/freezer,
+/area/ruin/powered/gluttony)
+"q" = (
+/obj/item/trash/syndi_cakes,
+/turf/simulated/floor/plasteel/freezer,
+/area/ruin/powered/gluttony)
+"r" = (
+/obj/effect/gluttony,
+/obj/machinery/light/small{
+ dir = 1
+ },
+/turf/simulated/floor/plasteel/freezer,
+/area/ruin/powered/gluttony)
+"t" = (
+/obj/machinery/light/small{
+ dir = 1
+ },
+/turf/simulated/floor/plasteel/freezer,
+/area/ruin/powered/gluttony)
+"v" = (
+/obj/machinery/light/small,
+/turf/simulated/floor/plasteel/freezer,
+/area/ruin/powered/gluttony)
+"z" = (
+/obj/item/trash/plate,
+/obj/machinery/light/small{
+ dir = 8
+ },
+/turf/simulated/floor/plasteel/freezer,
+/area/ruin/powered/gluttony)
+"A" = (
+/obj/machinery/light/small{
+ dir = 4
+ },
+/turf/simulated/floor/plasteel/freezer,
+/area/ruin/powered/gluttony)
+"R" = (
+/turf/simulated/wall/indestructible/uranium,
+/area/ruin/powered/gluttony)
+"S" = (
+/obj/machinery/door/airlock/uranium,
+/obj/structure/fans/tiny/invisible,
+/turf/simulated/floor/plasteel/freezer,
+/area/ruin/powered/gluttony)
+
+(1,1,1) = {"
+a
+a
+a
+b
+b
+a
+a
+b
+a
+b
+b
+b
+b
+b
+b
+b
+a
+a
+a
+a
+"}
+(2,1,1) = {"
+a
+a
+a
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+a
+a
+a
+a
+"}
+(3,1,1) = {"
+b
+a
+a
+a
+b
+b
+b
+c
+c
+c
+b
+c
+c
+c
+b
+b
+a
+a
+a
+a
+"}
+(4,1,1) = {"
+b
+a
+a
+a
+b
+b
+b
+c
+R
+R
+S
+R
+R
+c
+b
+a
+a
+a
+a
+a
+"}
+(5,1,1) = {"
+b
+b
+a
+a
+a
+b
+b
+c
+R
+h
+i
+o
+R
+c
+b
+a
+a
+a
+a
+a
+"}
+(6,1,1) = {"
+a
+a
+a
+a
+a
+b
+b
+c
+R
+i
+i
+v
+R
+c
+b
+b
+b
+b
+b
+a
+"}
+(7,1,1) = {"
+a
+b
+b
+b
+b
+b
+b
+c
+R
+i
+l
+i
+R
+c
+b
+b
+b
+b
+b
+a
+"}
+(8,1,1) = {"
+a
+b
+c
+c
+c
+c
+c
+c
+R
+t
+i
+m
+R
+c
+c
+c
+c
+c
+c
+b
+"}
+(9,1,1) = {"
+b
+b
+c
+R
+R
+R
+R
+R
+R
+g
+m
+v
+R
+R
+R
+R
+R
+R
+c
+b
+"}
+(10,1,1) = {"
+a
+b
+c
+R
+e
+R
+r
+g
+g
+g
+g
+i
+p
+i
+z
+l
+i
+R
+c
+b
+"}
+(11,1,1) = {"
+a
+b
+c
+R
+f
+g
+g
+g
+g
+g
+n
+d
+i
+i
+i
+i
+i
+S
+b
+b
+"}
+(12,1,1) = {"
+a
+b
+c
+R
+e
+R
+r
+g
+g
+g
+i
+g
+i
+l
+A
+i
+q
+R
+c
+b
+"}
+(13,1,1) = {"
+a
+b
+c
+R
+R
+R
+R
+R
+R
+g
+i
+v
+R
+R
+R
+R
+R
+R
+c
+b
+"}
+(14,1,1) = {"
+a
+b
+c
+c
+c
+c
+c
+c
+R
+r
+i
+i
+R
+c
+c
+c
+c
+c
+c
+b
+"}
+(15,1,1) = {"
+a
+b
+b
+b
+b
+b
+b
+c
+R
+i
+g
+i
+R
+c
+b
+b
+b
+b
+b
+b
+"}
+(16,1,1) = {"
+b
+b
+b
+a
+b
+b
+b
+c
+R
+j
+i
+v
+R
+c
+b
+b
+b
+a
+a
+a
+"}
+(17,1,1) = {"
+b
+b
+b
+a
+b
+b
+b
+c
+R
+i
+n
+i
+R
+c
+b
+b
+b
+a
+a
+a
+"}
+(18,1,1) = {"
+a
+a
+a
+a
+b
+b
+b
+c
+R
+R
+S
+R
+R
+c
+b
+b
+b
+a
+a
+a
+"}
+(19,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+c
+c
+c
+b
+c
+c
+c
+b
+b
+a
+a
+a
+a
+"}
+(20,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+b
+b
+b
+b
+b
+b
+b
+a
+a
+b
+a
+a
+a
+"}
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_greed.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_greed.dmm
new file mode 100644
index 00000000000..e1082c88664
--- /dev/null
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_greed.dmm
@@ -0,0 +1,577 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"b" = (
+/turf/simulated/mineral/volcanic/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"c" = (
+/turf/simulated/floor/plating/lava/smooth/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"d" = (
+/obj/effect/baseturf_helper/lava_land/surface,
+/turf/simulated/floor/engine/cult,
+/area/ruin/powered/greed)
+"e" = (
+/obj/structure/table/wood/poker,
+/obj/item/gun/projectile/revolver/russian/soul,
+/obj/machinery/light/small{
+ dir = 1
+ },
+/turf/simulated/floor/carpet{
+ icon_state = "carpetsymbol"
+ },
+/area/ruin/powered/greed)
+"f" = (
+/obj/structure/cursed_slot_machine,
+/turf/simulated/floor/carpet{
+ icon_state = "carpetsymbol"
+ },
+/area/ruin/powered/greed)
+"g" = (
+/obj/structure/table/wood/poker,
+/obj/item/coin/mythril,
+/obj/machinery/light/small{
+ dir = 1
+ },
+/turf/simulated/floor/carpet{
+ icon_state = "carpetsymbol"
+ },
+/area/ruin/powered/greed)
+"h" = (
+/obj/structure/table/wood/poker,
+/obj/item/coin/diamond,
+/turf/simulated/floor/carpet{
+ icon_state = "carpetsymbol"
+ },
+/area/ruin/powered/greed)
+"i" = (
+/turf/simulated/floor/carpet{
+ icon_state = "carpetsymbol"
+ },
+/area/ruin/powered/greed)
+"j" = (
+/obj/structure/table/wood/poker,
+/obj/item/coin/adamantine,
+/turf/simulated/floor/carpet{
+ icon_state = "carpetsymbol"
+ },
+/area/ruin/powered/greed)
+"k" = (
+/obj/machinery/computer/arcade/battle{
+ emagged = 1
+ },
+/turf/simulated/floor/engine/cult,
+/area/ruin/powered/greed)
+"l" = (
+/obj/item/coin/gold,
+/turf/simulated/floor/engine/cult,
+/area/ruin/powered/greed)
+"m" = (
+/turf/simulated/floor/engine/cult,
+/area/ruin/powered/greed)
+"n" = (
+/obj/structure/table/wood/poker,
+/obj/item/stack/spacecash/c1000,
+/turf/simulated/floor/engine/cult,
+/area/ruin/powered/greed)
+"o" = (
+/obj/item/storage/bag/money,
+/turf/simulated/floor/engine/cult,
+/area/ruin/powered/greed)
+"p" = (
+/obj/structure/table/wood/poker,
+/obj/item/stack/ore/gold,
+/turf/simulated/floor/engine/cult,
+/area/ruin/powered/greed)
+"q" = (
+/obj/structure/table/wood/poker,
+/obj/item/stack/spacecash/c20,
+/obj/item/stack/spacecash/c50,
+/obj/machinery/light/small{
+ brightness_range = 3;
+ dir = 8
+ },
+/turf/simulated/floor/engine/cult,
+/area/ruin/powered/greed)
+"r" = (
+/obj/structure/table/wood/poker,
+/obj/item/stack/spacecash/c500,
+/obj/item/stack/spacecash/c100,
+/obj/item/stack/spacecash/c1000,
+/turf/simulated/floor/engine/cult,
+/area/ruin/powered/greed)
+"s" = (
+/obj/structure/table/wood/poker,
+/obj/item/stack/spacecash/c200,
+/turf/simulated/floor/engine/cult,
+/area/ruin/powered/greed)
+"u" = (
+/obj/structure/table/wood/poker,
+/obj/item/stack/spacecash/c500,
+/obj/item/stack/spacecash/c100,
+/obj/item/stack/spacecash/c1000,
+/obj/machinery/light/small{
+ dir = 4
+ },
+/turf/simulated/floor/engine/cult,
+/area/ruin/powered/greed)
+"v" = (
+/obj/item/coin/gold,
+/obj/machinery/light/small,
+/turf/simulated/floor/engine/cult,
+/area/ruin/powered/greed)
+"w" = (
+/obj/item/storage/bag/money,
+/obj/machinery/light/small,
+/turf/simulated/floor/engine/cult,
+/area/ruin/powered/greed)
+"J" = (
+/obj/machinery/door/airlock/gold,
+/obj/structure/fans/tiny/invisible,
+/turf/simulated/floor/engine/cult,
+/area/ruin/powered/greed)
+"W" = (
+/turf/simulated/wall/cult,
+/area/ruin/powered/greed)
+
+(1,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+b
+"}
+(2,1,1) = {"
+a
+b
+b
+a
+a
+a
+a
+a
+a
+b
+b
+b
+a
+a
+a
+a
+a
+b
+b
+b
+"}
+(3,1,1) = {"
+a
+b
+b
+b
+b
+b
+a
+a
+a
+b
+a
+a
+a
+a
+a
+a
+b
+b
+b
+b
+"}
+(4,1,1) = {"
+a
+a
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+b
+b
+"}
+(5,1,1) = {"
+a
+a
+a
+b
+b
+a
+a
+c
+c
+c
+c
+c
+c
+c
+a
+a
+a
+a
+b
+a
+"}
+(6,1,1) = {"
+b
+a
+a
+a
+a
+a
+c
+c
+W
+W
+W
+W
+W
+c
+a
+a
+a
+a
+b
+a
+"}
+(7,1,1) = {"
+b
+a
+a
+a
+c
+c
+c
+W
+W
+n
+q
+s
+W
+c
+c
+c
+c
+a
+a
+a
+"}
+(8,1,1) = {"
+a
+a
+a
+a
+c
+W
+W
+W
+k
+o
+l
+m
+W
+W
+W
+W
+c
+a
+a
+a
+"}
+(9,1,1) = {"
+a
+a
+b
+a
+c
+W
+e
+h
+l
+m
+m
+m
+l
+m
+v
+W
+W
+a
+a
+a
+"}
+(10,1,1) = {"
+b
+b
+b
+a
+c
+W
+f
+i
+m
+l
+d
+o
+m
+m
+m
+m
+J
+a
+a
+a
+"}
+(11,1,1) = {"
+a
+a
+b
+a
+c
+W
+g
+j
+l
+m
+m
+l
+m
+l
+w
+W
+W
+a
+a
+a
+"}
+(12,1,1) = {"
+a
+a
+a
+a
+c
+W
+W
+W
+k
+o
+m
+l
+W
+W
+W
+W
+c
+a
+a
+a
+"}
+(13,1,1) = {"
+a
+a
+a
+a
+c
+c
+c
+W
+W
+p
+u
+r
+W
+c
+c
+c
+c
+a
+a
+a
+"}
+(14,1,1) = {"
+b
+b
+a
+a
+a
+a
+c
+c
+W
+W
+W
+W
+W
+c
+a
+a
+a
+a
+a
+a
+"}
+(15,1,1) = {"
+b
+b
+a
+a
+a
+a
+a
+c
+c
+c
+c
+c
+c
+c
+a
+a
+a
+a
+a
+a
+"}
+(16,1,1) = {"
+b
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+"}
+(17,1,1) = {"
+a
+a
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+"}
+(18,1,1) = {"
+a
+a
+a
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+a
+a
+b
+b
+b
+b
+b
+"}
+(19,1,1) = {"
+a
+a
+a
+b
+b
+b
+b
+a
+a
+a
+b
+b
+b
+b
+a
+b
+b
+b
+b
+b
+"}
+(20,1,1) = {"
+a
+a
+a
+a
+b
+b
+a
+a
+a
+a
+a
+a
+b
+b
+b
+b
+b
+b
+b
+b
+"}
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm
new file mode 100644
index 00000000000..645f7c1e4c7
--- /dev/null
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm
@@ -0,0 +1,731 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/template_noop)
+"b" = (
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"c" = (
+/obj/structure/lattice,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"d" = (
+/turf/simulated/wall,
+/area/ruin/unpowered)
+"e" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/plating{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"f" = (
+/obj/structure/table/wood,
+/obj/item/storage/box/cups,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"g" = (
+/obj/structure/reagent_dispensers/water_cooler{
+ name = "punch cooler";
+ reagent_id = /datum/reagent/consumable/ethanol/bacchus_blessing
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"h" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"i" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"j" = (
+/obj/item/reagent_containers/food/snacks/mushroompizzaslice,
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/plating{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"k" = (
+/obj/structure/table/wood,
+/obj/effect/spawner/lootdrop/pizzaparty,
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"l" = (
+/obj/machinery/light{
+ dir = 4
+ },
+/obj/structure/table/wood,
+/obj/effect/spawner/lootdrop/pizzaparty,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/cobweb2,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"m" = (
+/obj/item/chair/wood/wings,
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/plating{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"n" = (
+/obj/structure/glowshroom/single,
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"o" = (
+/obj/item/trash/plate,
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"p" = (
+/obj/effect/decal/remains/human,
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"q" = (
+/obj/item/chair/wood/wings,
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"r" = (
+/obj/structure/chair/wood/wings,
+/obj/effect/decal/remains/human,
+/obj/item/clothing/head/festive{
+ desc = "A festive party hat with the name 'timmy' scribbled on the front.";
+ name = "party hat"
+ },
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"s" = (
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"t" = (
+/obj/structure/chair/wood/wings,
+/obj/effect/decal/remains/human,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"u" = (
+/obj/structure/glowshroom/single,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"v" = (
+/obj/structure/lattice,
+/obj/item/chair/wood/wings,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"w" = (
+/obj/item/kitchen/utensil/fork,
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"x" = (
+/obj/structure/table/wood,
+/obj/effect/spawner/lootdrop/pizzaparty,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"y" = (
+/obj/structure/table/wood,
+/obj/item/trash/plate,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"z" = (
+/obj/structure/table/wood,
+/obj/structure/glowshroom/single,
+/obj/item/a_gift,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"A" = (
+/obj/structure/table/wood,
+/obj/item/trash/plate,
+/obj/item/kitchen/utensil/fork,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"B" = (
+/obj/effect/baseturf_helper/lava_land/surface,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"C" = (
+/obj/structure/chair/wood/wings{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/plating{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"D" = (
+/obj/structure/table/wood,
+/obj/item/reagent_containers/food/snacks/margheritaslice,
+/obj/item/trash/plate,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"E" = (
+/obj/structure/table/wood,
+/obj/item/reagent_containers/food/snacks/meatpizzaslice,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"F" = (
+/obj/structure/table/wood,
+/obj/item/reagent_containers/food/snacks/sliceable/birthdaycake,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"G" = (
+/obj/structure/table/wood,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"H" = (
+/obj/item/chair/wood/wings,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"I" = (
+/obj/item/kitchen/utensil/fork,
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/plating{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"J" = (
+/obj/structure/glowshroom/single,
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/plating{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"K" = (
+/obj/structure/chair/wood/wings{
+ dir = 1
+ },
+/obj/effect/decal/remains/human,
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"L" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/plating{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"M" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/item/a_gift,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"N" = (
+/obj/structure/lattice,
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"O" = (
+/obj/item/kitchen/knife,
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"P" = (
+/obj/machinery/light{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/simulated/floor/wood{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+"Q" = (
+/turf/simulated/floor/plating{
+ oxygen = 14;
+ nitrogen = 23;
+ temperature = 300
+ },
+/area/ruin/unpowered)
+
+(1,1,1) = {"
+a
+a
+b
+b
+a
+a
+b
+b
+b
+b
+b
+b
+b
+b
+a
+a
+a
+a
+"}
+(2,1,1) = {"
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+c
+c
+b
+b
+b
+b
+a
+a
+"}
+(3,1,1) = {"
+b
+b
+b
+b
+b
+b
+b
+b
+c
+c
+e
+e
+c
+c
+b
+b
+b
+a
+"}
+(4,1,1) = {"
+b
+b
+b
+b
+d
+b
+c
+c
+e
+h
+h
+e
+Q
+e
+d
+b
+b
+a
+"}
+(5,1,1) = {"
+a
+b
+b
+b
+d
+b
+m
+e
+w
+h
+w
+h
+h
+e
+d
+b
+b
+b
+"}
+(6,1,1) = {"
+a
+b
+b
+b
+d
+f
+n
+h
+h
+c
+e
+M
+e
+c
+b
+b
+b
+b
+"}
+(7,1,1) = {"
+b
+b
+b
+b
+d
+g
+o
+h
+h
+C
+J
+h
+d
+b
+b
+b
+b
+b
+"}
+(8,1,1) = {"
+b
+b
+b
+b
+e
+h
+p
+q
+x
+D
+K
+M
+d
+b
+b
+b
+b
+b
+"}
+(9,1,1) = {"
+b
+b
+b
+c
+e
+i
+h
+r
+y
+E
+h
+h
+c
+b
+b
+b
+b
+b
+"}
+(10,1,1) = {"
+b
+b
+b
+c
+e
+j
+h
+s
+z
+F
+q
+N
+c
+b
+b
+b
+b
+b
+"}
+(11,1,1) = {"
+b
+b
+b
+b
+e
+e
+h
+t
+A
+G
+q
+h
+c
+b
+b
+b
+b
+b
+"}
+(12,1,1) = {"
+b
+b
+b
+b
+d
+k
+h
+s
+B
+H
+h
+O
+d
+b
+b
+b
+b
+b
+"}
+(13,1,1) = {"
+b
+b
+b
+b
+d
+k
+h
+u
+s
+s
+o
+n
+d
+b
+b
+b
+b
+a
+"}
+(14,1,1) = {"
+b
+b
+b
+b
+d
+l
+i
+h
+e
+I
+L
+P
+d
+b
+b
+b
+b
+a
+"}
+(15,1,1) = {"
+b
+b
+b
+b
+d
+d
+e
+e
+N
+e
+e
+d
+d
+b
+b
+b
+b
+a
+"}
+(16,1,1) = {"
+a
+b
+b
+b
+b
+b
+c
+v
+b
+c
+b
+b
+b
+b
+b
+b
+b
+a
+"}
+(17,1,1) = {"
+a
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+b
+a
+a
+a
+"}
+(18,1,1) = {"
+a
+a
+a
+a
+b
+b
+b
+b
+b
+b
+b
+b
+a
+a
+a
+a
+a
+a
+"}
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_pride.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_pride.dmm
new file mode 100644
index 00000000000..ff9a27ee711
--- /dev/null
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_pride.dmm
@@ -0,0 +1,304 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"b" = (
+/turf/simulated/mineral/volcanic/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"c" = (
+/turf/simulated/floor/plating/lava/smooth/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"d" = (
+/obj/effect/baseturf_helper/lava_land/surface,
+/turf/simulated/floor/mineral/silver,
+/area/ruin/powered/pride)
+"e" = (
+/obj/structure/mirror{
+ pixel_x = -32
+ },
+/turf/simulated/floor/mineral/silver,
+/area/ruin/powered/pride)
+"f" = (
+/obj/structure/mirror{
+ pixel_x = 32
+ },
+/turf/simulated/floor/mineral/silver,
+/area/ruin/powered/pride)
+"g" = (
+/turf/simulated/floor/mineral/silver,
+/area/ruin/powered/pride)
+"j" = (
+/obj/structure/mirror{
+ pixel_x = -32
+ },
+/obj/machinery/light/small{
+ dir = 1
+ },
+/turf/simulated/floor/mineral/silver,
+/area/ruin/powered/pride)
+"k" = (
+/obj/structure/mirror{
+ pixel_x = 32
+ },
+/obj/machinery/light/small{
+ dir = 1
+ },
+/turf/simulated/floor/mineral/silver,
+/area/ruin/powered/pride)
+"l" = (
+/obj/structure/mirror{
+ pixel_x = -32
+ },
+/obj/machinery/light/small{
+ brightness_range = 3;
+ dir = 8
+ },
+/turf/simulated/floor/mineral/silver,
+/area/ruin/powered/pride)
+"m" = (
+/obj/structure/mirror{
+ pixel_x = 32
+ },
+/obj/machinery/light/small{
+ dir = 4
+ },
+/turf/simulated/floor/mineral/silver,
+/area/ruin/powered/pride)
+"r" = (
+/obj/machinery/light/small,
+/turf/simulated/floor/mineral/silver,
+/area/ruin/powered/pride)
+"G" = (
+/turf/simulated/wall/mineral/diamond,
+/area/ruin/powered/pride)
+"O" = (
+/obj/structure/mirror/magic/pride,
+/turf/simulated/wall/mineral/diamond,
+/area/ruin/powered/pride)
+"Y" = (
+/obj/machinery/door/airlock/diamond,
+/turf/simulated/floor/mineral/silver{
+ blocks_air = 1
+ },
+/area/ruin/powered/pride)
+
+(1,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(2,1,1) = {"
+a
+a
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+a
+"}
+(3,1,1) = {"
+b
+c
+c
+G
+G
+G
+G
+G
+G
+G
+G
+G
+G
+G
+G
+G
+G
+G
+c
+a
+"}
+(4,1,1) = {"
+c
+c
+G
+G
+G
+j
+e
+e
+l
+e
+e
+l
+e
+e
+l
+e
+e
+G
+c
+a
+"}
+(5,1,1) = {"
+c
+G
+G
+G
+G
+G
+g
+g
+g
+g
+g
+g
+g
+g
+g
+g
+r
+G
+a
+a
+"}
+(6,1,1) = {"
+c
+G
+G
+G
+G
+G
+O
+g
+g
+g
+d
+g
+g
+g
+g
+g
+g
+Y
+a
+a
+"}
+(7,1,1) = {"
+c
+G
+G
+G
+G
+G
+g
+g
+g
+g
+g
+g
+g
+g
+g
+g
+r
+G
+c
+a
+"}
+(8,1,1) = {"
+c
+c
+G
+G
+G
+k
+f
+f
+m
+f
+f
+m
+f
+f
+m
+f
+f
+G
+c
+a
+"}
+(9,1,1) = {"
+b
+c
+c
+G
+G
+G
+G
+G
+G
+G
+G
+G
+G
+G
+G
+G
+G
+G
+c
+a
+"}
+(10,1,1) = {"
+b
+b
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+a
+"}
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_puzzle.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_puzzle.dmm
new file mode 100644
index 00000000000..75b4c619445
--- /dev/null
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_puzzle.dmm
@@ -0,0 +1,47 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/lavaland/surface/outdoors)
+"b" = (
+/obj/effect/sliding_puzzle/lavaland,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"c" = (
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+
+(1,1,1) = {"
+a
+a
+a
+a
+a
+"}
+(2,1,1) = {"
+a
+c
+c
+c
+a
+"}
+(3,1,1) = {"
+a
+c
+b
+c
+a
+"}
+(4,1,1) = {"
+a
+c
+c
+c
+a
+"}
+(5,1,1) = {"
+a
+a
+a
+a
+a
+"}
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm
new file mode 100644
index 00000000000..1b7783388de
--- /dev/null
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm
@@ -0,0 +1,58 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/lavaland/surface/outdoors)
+"b" = (
+/turf/simulated/mineral/volcanic/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"c" = (
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"d" = (
+/obj/mecha/working/ripley/mining{
+ ruin_mecha = 1
+ },
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"e" = (
+/obj/item/clothing/shoes/workboots/mining,
+/obj/item/clothing/under/rank/miner/lavaland,
+/obj/effect/decal/remains/human,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+
+(1,1,1) = {"
+a
+b
+b
+b
+a
+"}
+(2,1,1) = {"
+b
+c
+b
+c
+b
+"}
+(3,1,1) = {"
+b
+c
+d
+e
+b
+"}
+(4,1,1) = {"
+b
+c
+c
+b
+b
+"}
+(5,1,1) = {"
+b
+b
+b
+b
+a
+"}
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_sloth.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_sloth.dmm
new file mode 100644
index 00000000000..bac638bd3c0
--- /dev/null
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_sloth.dmm
@@ -0,0 +1,651 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/unsimulated/wall,
+/area/ruin/unpowered)
+"b" = (
+/turf/simulated/floor/plating/lava/smooth/lava_land_surface,
+/area/ruin/unpowered)
+"c" = (
+/obj/item/paper/fluff/stations/lavaland/sloth/note,
+/turf/simulated/floor/sepia{
+ blocks_air = 0;
+ slowdown = 10
+ },
+/area/ruin/unpowered)
+"d" = (
+/turf/simulated/floor/sepia{
+ blocks_air = 0;
+ slowdown = 10
+ },
+/area/ruin/unpowered)
+"e" = (
+/obj/machinery/door/airlock/wood,
+/turf/simulated/floor/sepia{
+ blocks_air = 0;
+ slowdown = 10
+ },
+/area/ruin/unpowered)
+"f" = (
+/obj/structure/table/wood,
+/obj/item/reagent_containers/food/snacks/grown/citrus/orange,
+/turf/simulated/floor/sepia{
+ blocks_air = 0;
+ slowdown = 10
+ },
+/area/ruin/unpowered)
+"g" = (
+/obj/structure/bed,
+/obj/item/bedsheet/brown,
+/turf/simulated/floor/sepia{
+ blocks_air = 0;
+ slowdown = 10
+ },
+/area/ruin/unpowered)
+"h" = (
+/obj/effect/baseturf_helper/lava_land/surface,
+/turf/simulated/floor/sepia{
+ blocks_air = 0;
+ slowdown = 10
+ },
+/area/ruin/unpowered)
+
+(1,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(2,1,1) = {"
+a
+b
+b
+b
+b
+b
+b
+b
+b
+a
+"}
+(3,1,1) = {"
+a
+b
+a
+a
+a
+a
+a
+a
+b
+a
+"}
+(4,1,1) = {"
+a
+b
+a
+c
+d
+d
+f
+a
+b
+a
+"}
+(5,1,1) = {"
+a
+b
+a
+d
+d
+d
+g
+a
+b
+a
+"}
+(6,1,1) = {"
+a
+b
+a
+d
+a
+a
+a
+a
+b
+a
+"}
+(7,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(8,1,1) = {"
+a
+b
+a
+a
+a
+a
+d
+a
+b
+a
+"}
+(9,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(10,1,1) = {"
+a
+b
+a
+d
+a
+a
+a
+a
+b
+a
+"}
+(11,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(12,1,1) = {"
+a
+b
+a
+a
+a
+a
+d
+a
+b
+a
+"}
+(13,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(14,1,1) = {"
+a
+b
+a
+d
+a
+a
+a
+a
+b
+a
+"}
+(15,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(16,1,1) = {"
+a
+b
+a
+a
+a
+a
+d
+a
+b
+a
+"}
+(17,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(18,1,1) = {"
+a
+b
+a
+d
+a
+a
+a
+a
+b
+a
+"}
+(19,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(20,1,1) = {"
+a
+b
+a
+a
+a
+a
+d
+a
+b
+a
+"}
+(21,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(22,1,1) = {"
+a
+b
+a
+d
+a
+a
+a
+a
+b
+a
+"}
+(23,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(24,1,1) = {"
+a
+b
+a
+a
+a
+a
+d
+a
+b
+a
+"}
+(25,1,1) = {"
+a
+b
+a
+d
+h
+d
+d
+a
+b
+a
+"}
+(26,1,1) = {"
+a
+b
+a
+d
+a
+a
+a
+a
+b
+a
+"}
+(27,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(28,1,1) = {"
+a
+b
+a
+a
+a
+a
+d
+a
+b
+a
+"}
+(29,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(30,1,1) = {"
+a
+b
+a
+d
+a
+a
+a
+a
+b
+a
+"}
+(31,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(32,1,1) = {"
+a
+b
+a
+a
+a
+a
+d
+a
+b
+a
+"}
+(33,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(34,1,1) = {"
+a
+b
+a
+d
+a
+a
+a
+a
+b
+a
+"}
+(35,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(36,1,1) = {"
+a
+b
+a
+a
+a
+a
+d
+a
+b
+a
+"}
+(37,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(38,1,1) = {"
+a
+b
+a
+d
+a
+a
+a
+a
+b
+a
+"}
+(39,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(40,1,1) = {"
+a
+b
+a
+a
+a
+a
+d
+a
+b
+a
+"}
+(41,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(42,1,1) = {"
+a
+b
+a
+d
+a
+a
+a
+a
+b
+a
+"}
+(43,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(44,1,1) = {"
+a
+b
+a
+a
+a
+a
+d
+a
+b
+a
+"}
+(45,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(46,1,1) = {"
+a
+b
+a
+d
+a
+a
+a
+a
+b
+a
+"}
+(47,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(48,1,1) = {"
+a
+b
+a
+a
+a
+a
+d
+a
+b
+a
+"}
+(49,1,1) = {"
+a
+b
+a
+d
+d
+d
+d
+a
+b
+a
+"}
+(50,1,1) = {"
+a
+a
+a
+a
+e
+e
+a
+a
+a
+a
+"}
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm
new file mode 100644
index 00000000000..3b2dd805189
--- /dev/null
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm
@@ -0,0 +1,261 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/template_noop)
+"b" = (
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"c" = (
+/obj/structure/sign/mining/survival{
+ pixel_y = -32
+ },
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"d" = (
+/turf/simulated/wall/mineral/titanium/survival/pod,
+/area/ruin/powered)
+"e" = (
+/obj/structure/sign/mining/survival{
+ dir = 4;
+ pixel_x = 32
+ },
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"f" = (
+/obj/structure/fans,
+/turf/simulated/floor/pod/dark,
+/area/ruin/powered)
+"g" = (
+/obj/machinery/smartfridge/survival_pod/empty,
+/turf/simulated/floor/pod/dark,
+/area/ruin/powered)
+"h" = (
+/obj/item/gps/computer,
+/obj/structure/tubes,
+/turf/simulated/floor/pod/dark,
+/area/ruin/powered)
+"i" = (
+/obj/structure/sign/mining/survival{
+ dir = 8;
+ pixel_x = -32
+ },
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"j" = (
+/obj/effect/decal/cleanable/blood/drip,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"k" = (
+/obj/machinery/sleeper/survival_pod,
+/turf/simulated/floor/pod/dark,
+/area/ruin/powered)
+"l" = (
+/obj/item/pickaxe,
+/obj/effect/decal/cleanable/blood,
+/turf/simulated/floor/pod/dark,
+/area/ruin/powered)
+"m" = (
+/obj/structure/bed/pod,
+/obj/item/bedsheet/black,
+/obj/structure/tubes,
+/obj/machinery/light/small{
+ dir = 4
+ },
+/turf/simulated/floor/pod/dark,
+/area/ruin/powered)
+"n" = (
+/obj/effect/decal/cleanable/blood,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"o" = (
+/obj/effect/decal/cleanable/blood,
+/mob/living/simple_animal/hostile/asteroid/goliath/beast{
+ health = 0
+ },
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"p" = (
+/obj/structure/table/survival_pod,
+/obj/item/kitchen/knife/combat/survival,
+/turf/simulated/floor/pod/dark,
+/area/ruin/powered)
+"q" = (
+/obj/effect/mob_spawn/human/miner/explorer{
+ brute_damage = 150;
+ oxy_damage = 50
+ },
+/obj/effect/decal/cleanable/blood,
+/obj/effect/decal/cleanable/blood/drip,
+/obj/effect/decal/cleanable/blood/tracks,
+/turf/simulated/floor/pod/dark,
+/area/ruin/powered)
+"r" = (
+/obj/structure/tubes,
+/obj/item/crowbar,
+/obj/effect/decal/cleanable/blood/drip,
+/obj/effect/baseturf_helper/lava_land/surface,
+/turf/simulated/floor/pod/dark,
+/area/ruin/powered)
+"s" = (
+/obj/effect/decal/cleanable/blood/tracks,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"t" = (
+/obj/machinery/door/airlock/survival_pod/glass,
+/obj/effect/decal/cleanable/blood/tracks,
+/turf/simulated/floor/pod/dark,
+/area/ruin/powered)
+"v" = (
+/obj/effect/decal/cleanable/blood/drip,
+/obj/effect/decal/cleanable/blood,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"w" = (
+/obj/structure/sign/mining/survival{
+ pixel_y = 32
+ },
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"x" = (
+/obj/structure/sign/mining{
+ pixel_y = 32
+ },
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"y" = (
+/obj/effect/decal/cleanable/blood/tracks{
+ dir = 4
+ },
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+
+(1,1,1) = {"
+a
+a
+a
+b
+b
+b
+b
+b
+a
+a
+a
+"}
+(2,1,1) = {"
+a
+a
+b
+b
+e
+b
+e
+b
+b
+a
+a
+"}
+(3,1,1) = {"
+a
+a
+b
+d
+d
+d
+d
+d
+b
+a
+a
+"}
+(4,1,1) = {"
+a
+b
+c
+d
+f
+k
+p
+d
+w
+b
+b
+"}
+(5,1,1) = {"
+a
+b
+b
+d
+g
+l
+q
+t
+v
+b
+b
+"}
+(6,1,1) = {"
+b
+b
+c
+d
+h
+m
+r
+d
+x
+b
+b
+"}
+(7,1,1) = {"
+a
+b
+b
+d
+d
+d
+d
+d
+y
+j
+j
+"}
+(8,1,1) = {"
+a
+a
+b
+b
+i
+b
+i
+j
+j
+b
+b
+"}
+(9,1,1) = {"
+a
+a
+b
+b
+j
+n
+s
+b
+a
+a
+a
+"}
+(10,1,1) = {"
+a
+a
+a
+a
+a
+o
+j
+b
+a
+a
+a
+"}
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm
new file mode 100644
index 00000000000..0f756d15090
--- /dev/null
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm
@@ -0,0 +1,431 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/simulated/mineral/volcanic/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"b" = (
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"c" = (
+/obj/machinery/abductor/experiment,
+/turf/unsimulated/floor/abductor,
+/area/ruin/unpowered)
+"d" = (
+/turf/simulated/wall/mineral/abductor,
+/area/ruin/unpowered)
+"e" = (
+/turf/unsimulated/floor/abductor,
+/area/ruin/unpowered)
+"g" = (
+/obj/machinery/abductor/pad,
+/turf/unsimulated/floor/abductor,
+/area/ruin/unpowered)
+"h" = (
+/obj/item/hemostat/alien,
+/turf/unsimulated/floor/abductor,
+/area/ruin/unpowered)
+"i" = (
+/obj/effect/mob_spawn/human/abductor,
+/turf/unsimulated/floor/abductor,
+/area/ruin/unpowered)
+"j" = (
+/obj/structure/closet/abductor,
+/turf/unsimulated/floor/abductor,
+/area/ruin/unpowered)
+"k" = (
+/obj/effect/baseturf_helper/lava_land/surface,
+/turf/unsimulated/floor/abductor,
+/area/ruin/unpowered)
+"l" = (
+/obj/machinery/optable/abductor,
+/obj/item/cautery/alien,
+/turf/unsimulated/floor/abductor,
+/area/ruin/unpowered)
+"m" = (
+/obj/structure/table/abductor,
+/obj/item/storage/box/alienhandcuffs,
+/turf/unsimulated/floor/abductor,
+/area/ruin/unpowered)
+"n" = (
+/obj/item/scalpel/alien,
+/obj/item/surgical_drapes,
+/turf/unsimulated/floor/abductor,
+/area/ruin/unpowered)
+"o" = (
+/obj/item/retractor/alien,
+/turf/unsimulated/floor/abductor,
+/area/ruin/unpowered)
+"p" = (
+/obj/machinery/abductor/gland_dispenser,
+/turf/unsimulated/floor/abductor,
+/area/ruin/unpowered)
+"q" = (
+/obj/structure/table/abductor,
+/obj/item/surgicaldrill/alien,
+/obj/item/circular_saw/alien,
+/turf/unsimulated/floor/abductor,
+/area/ruin/unpowered)
+"r" = (
+/obj/structure/bed/abductor,
+/turf/unsimulated/floor/abductor,
+/area/ruin/unpowered)
+
+(1,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(2,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(3,1,1) = {"
+a
+a
+a
+d
+a
+a
+a
+a
+a
+a
+"}
+(4,1,1) = {"
+a
+a
+d
+d
+a
+a
+a
+a
+a
+a
+"}
+(5,1,1) = {"
+a
+a
+d
+c
+e
+k
+a
+p
+d
+a
+"}
+(6,1,1) = {"
+a
+a
+d
+e
+h
+l
+n
+q
+d
+a
+"}
+(7,1,1) = {"
+a
+a
+d
+g
+i
+e
+o
+r
+d
+a
+"}
+(8,1,1) = {"
+a
+a
+d
+d
+j
+m
+j
+d
+d
+a
+"}
+(9,1,1) = {"
+a
+a
+b
+d
+d
+d
+d
+d
+b
+a
+"}
+(10,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(11,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(12,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(13,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(14,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(15,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(16,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(17,1,1) = {"
+a
+b
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(18,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(19,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+b
+a
+"}
+(20,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(21,1,1) = {"
+a
+b
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(22,1,1) = {"
+a
+b
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(23,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(24,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(25,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(26,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(27,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(28,1,1) = {"
+a
+b
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(29,1,1) = {"
+a
+b
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(30,1,1) = {"
+a
+b
+b
+b
+b
+b
+b
+b
+b
+a
+"}
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm
new file mode 100644
index 00000000000..63ffac70fd8
--- /dev/null
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm
@@ -0,0 +1,1557 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/template_noop)
+"b" = (
+/obj/structure/alien/weeds,
+/obj/structure/alien/resin/wall,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"c" = (
+/obj/structure/alien/weeds,
+/obj/effect/baseturf_helper/lava_land/surface,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"d" = (
+/obj/structure/alien/resin/wall,
+/obj/structure/alien/weeds,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"e" = (
+/obj/structure/alien/weeds,
+/obj/structure/alien/egg/burst,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"f" = (
+/obj/structure/alien/weeds,
+/obj/structure/alien/weeds,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"g" = (
+/obj/structure/alien/weeds,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"i" = (
+/obj/structure/alien/weeds,
+/obj/structure/bed/nest,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"j" = (
+/obj/structure/alien/weeds,
+/mob/living/simple_animal/hostile/alien,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"l" = (
+/obj/structure/alien/weeds/node,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"o" = (
+/obj/structure/alien/weeds,
+/obj/structure/bed/nest,
+/obj/effect/decal/cleanable/blood/gibs,
+/obj/item/gun/projectile/automatic/pistol,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"r" = (
+/obj/structure/alien/weeds,
+/obj/structure/alien/resin/wall,
+/obj/structure/alien/resin/wall,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"t" = (
+/obj/structure/alien/weeds,
+/mob/living/simple_animal/hostile/alien/sentinel,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"u" = (
+/obj/structure/alien/weeds,
+/obj/effect/decal/cleanable/blood/gibs,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"v" = (
+/obj/structure/alien/weeds/node,
+/obj/effect/decal/cleanable/blood,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"w" = (
+/obj/structure/alien/weeds,
+/obj/structure/bed/nest,
+/obj/structure/alien/resin/wall,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"y" = (
+/obj/structure/alien/weeds/node,
+/obj/structure/alien/resin/wall,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"z" = (
+/obj/structure/alien/weeds,
+/obj/structure/bed/nest,
+/obj/effect/decal/cleanable/blood/gibs,
+/obj/item/clothing/under/rank/security,
+/obj/item/clothing/suit/armor/vest,
+/obj/item/melee/baton/loaded,
+/obj/item/clothing/head/helmet,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"B" = (
+/obj/structure/alien/weeds,
+/obj/structure/alien/egg/burst,
+/obj/effect/decal/cleanable/blood/gibs,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"C" = (
+/obj/structure/alien/weeds,
+/obj/structure/alien/egg/burst,
+/obj/effect/decal/cleanable/blood,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"E" = (
+/obj/structure/alien/weeds,
+/mob/living/simple_animal/hostile/alien/drone{
+ plants_off = 1
+ },
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"F" = (
+/obj/structure/alien/weeds,
+/mob/living/simple_animal/hostile/alien/queen/large{
+ desc = "A gigantic alien who is in charge of the hive and all of its loyal servants.";
+ name = "alien queen";
+ pixel_x = -16;
+ plants_off = 1
+ },
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"G" = (
+/turf/simulated/floor/plating/lava/smooth/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"H" = (
+/obj/structure/alien/weeds,
+/obj/effect/decal/cleanable/blood,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"I" = (
+/obj/structure/alien/weeds,
+/obj/structure/bed/nest,
+/obj/effect/decal/cleanable/blood/gibs,
+/obj/effect/decal/cleanable/blood,
+/obj/item/clothing/under/syndicate,
+/obj/item/clothing/glasses/night,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"K" = (
+/obj/structure/alien/weeds/node,
+/mob/living/simple_animal/hostile/alien,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"L" = (
+/obj/structure/alien/weeds/node,
+/mob/living/simple_animal/hostile/alien/drone{
+ plants_off = 1
+ },
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"M" = (
+/obj/structure/alien/weeds,
+/obj/structure/bed/nest,
+/obj/effect/decal/cleanable/blood/gibs,
+/obj/item/tank/emergency_oxygen,
+/obj/item/clothing/suit/space/syndicate/orange,
+/obj/item/clothing/mask/gas,
+/obj/item/clothing/head/helmet/space/syndicate/orange,
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"O" = (
+/obj/structure/alien/weeds/node,
+/turf/template_noop,
+/area/ruin/unpowered/xenonest)
+"Q" = (
+/obj/structure/alien/weeds,
+/obj/effect/decal/cleanable/blood,
+/mob/living/simple_animal/hostile/alien/drone{
+ plants_off = 1
+ },
+/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/xenonest)
+"R" = (
+/obj/structure/alien/weeds,
+/turf/template_noop,
+/area/ruin/unpowered/xenonest)
+
+(1,1,1) = {"
+a
+a
+a
+G
+G
+G
+G
+G
+G
+G
+G
+G
+G
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(2,1,1) = {"
+a
+a
+a
+G
+b
+b
+b
+b
+b
+b
+b
+b
+G
+G
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(3,1,1) = {"
+a
+a
+G
+G
+b
+g
+e
+e
+b
+g
+g
+b
+b
+G
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(4,1,1) = {"
+a
+a
+G
+b
+b
+g
+g
+g
+g
+E
+g
+e
+b
+G
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(5,1,1) = {"
+a
+a
+G
+b
+g
+g
+y
+b
+b
+b
+y
+b
+b
+G
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(6,1,1) = {"
+a
+a
+G
+b
+g
+g
+w
+g
+F
+u
+I
+b
+b
+G
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(7,1,1) = {"
+a
+a
+G
+b
+e
+t
+g
+g
+g
+H
+u
+g
+b
+G
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(8,1,1) = {"
+a
+a
+G
+b
+i
+u
+b
+g
+l
+g
+t
+e
+b
+G
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(9,1,1) = {"
+a
+a
+G
+b
+o
+v
+g
+b
+g
+g
+e
+b
+b
+G
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(10,1,1) = {"
+a
+a
+G
+b
+g
+u
+b
+g
+g
+g
+y
+e
+b
+G
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(11,1,1) = {"
+a
+a
+G
+b
+b
+g
+t
+g
+g
+t
+g
+g
+b
+G
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+b
+b
+a
+"}
+(12,1,1) = {"
+a
+a
+G
+G
+b
+e
+g
+g
+g
+g
+g
+g
+b
+G
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+M
+i
+b
+b
+"}
+(13,1,1) = {"
+a
+a
+a
+G
+b
+b
+g
+g
+l
+g
+g
+b
+b
+G
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+e
+u
+Q
+g
+b
+"}
+(14,1,1) = {"
+a
+a
+a
+G
+G
+b
+b
+g
+g
+g
+b
+b
+G
+G
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+i
+g
+l
+g
+e
+b
+"}
+(15,1,1) = {"
+a
+a
+a
+a
+G
+G
+b
+b
+b
+b
+b
+G
+G
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+b
+g
+g
+g
+i
+b
+b
+"}
+(16,1,1) = {"
+a
+a
+a
+a
+a
+G
+b
+l
+l
+b
+G
+G
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+g
+j
+g
+e
+b
+b
+b
+a
+"}
+(17,1,1) = {"
+a
+a
+a
+a
+a
+a
+b
+E
+g
+b
+b
+G
+b
+b
+b
+b
+b
+b
+b
+b
+b
+g
+g
+b
+b
+b
+b
+a
+a
+a
+"}
+(18,1,1) = {"
+a
+a
+a
+a
+a
+a
+b
+g
+g
+E
+b
+b
+b
+g
+g
+g
+g
+g
+g
+b
+b
+g
+b
+b
+a
+a
+a
+a
+a
+a
+"}
+(19,1,1) = {"
+a
+a
+a
+a
+a
+a
+b
+b
+g
+g
+g
+b
+g
+g
+c
+g
+g
+g
+l
+g
+g
+g
+b
+a
+a
+a
+a
+a
+a
+a
+"}
+(20,1,1) = {"
+b
+b
+b
+b
+a
+a
+a
+b
+b
+g
+l
+g
+g
+g
+b
+b
+b
+b
+g
+g
+g
+b
+b
+a
+a
+a
+a
+a
+a
+a
+"}
+(21,1,1) = {"
+b
+e
+i
+b
+b
+b
+b
+b
+b
+g
+g
+g
+g
+b
+b
+a
+a
+b
+b
+g
+g
+b
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(22,1,1) = {"
+d
+f
+j
+g
+b
+b
+g
+g
+g
+g
+g
+g
+b
+b
+a
+a
+a
+b
+g
+g
+g
+b
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(23,1,1) = {"
+d
+g
+e
+l
+g
+g
+g
+b
+b
+g
+b
+b
+b
+a
+a
+a
+a
+b
+g
+g
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(24,1,1) = {"
+b
+b
+i
+i
+b
+b
+b
+b
+b
+g
+b
+a
+a
+a
+a
+a
+a
+b
+g
+g
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(25,1,1) = {"
+a
+b
+b
+b
+b
+a
+a
+a
+b
+E
+b
+b
+a
+a
+a
+a
+a
+b
+g
+L
+b
+b
+b
+a
+a
+a
+a
+a
+a
+b
+"}
+(26,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+b
+g
+g
+b
+a
+a
+a
+a
+a
+b
+g
+g
+g
+g
+b
+b
+b
+a
+a
+a
+b
+b
+"}
+(27,1,1) = {"
+a
+a
+a
+a
+a
+a
+b
+b
+b
+g
+g
+b
+b
+a
+a
+a
+a
+b
+b
+g
+g
+g
+g
+g
+b
+b
+b
+b
+y
+g
+"}
+(28,1,1) = {"
+a
+a
+a
+a
+a
+b
+b
+B
+g
+g
+l
+e
+b
+a
+a
+a
+b
+b
+g
+g
+b
+b
+g
+g
+g
+b
+O
+R
+g
+g
+"}
+(29,1,1) = {"
+a
+a
+a
+a
+a
+b
+z
+C
+j
+g
+e
+i
+b
+a
+a
+a
+b
+g
+g
+b
+b
+b
+b
+g
+l
+b
+O
+R
+g
+g
+"}
+(30,1,1) = {"
+a
+a
+a
+a
+a
+b
+i
+u
+g
+i
+i
+b
+b
+a
+a
+a
+b
+g
+b
+b
+a
+a
+b
+b
+b
+b
+b
+y
+g
+g
+"}
+(31,1,1) = {"
+a
+a
+a
+a
+a
+b
+b
+b
+g
+b
+b
+b
+a
+a
+a
+a
+b
+g
+b
+b
+a
+a
+a
+a
+a
+a
+a
+b
+g
+g
+"}
+(32,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+b
+g
+b
+a
+a
+a
+a
+a
+a
+b
+g
+g
+b
+a
+a
+a
+a
+a
+a
+a
+b
+g
+g
+"}
+(33,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+b
+g
+b
+a
+a
+a
+a
+a
+a
+b
+b
+l
+b
+a
+a
+a
+a
+a
+a
+b
+b
+g
+a
+"}
+(34,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+b
+l
+b
+a
+a
+a
+a
+a
+a
+a
+b
+g
+b
+a
+a
+a
+a
+a
+a
+b
+a
+a
+a
+"}
+(35,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+b
+g
+b
+a
+a
+a
+a
+a
+a
+a
+b
+g
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(36,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+b
+g
+b
+a
+a
+a
+a
+a
+a
+b
+b
+g
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(37,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+b
+g
+b
+a
+a
+a
+a
+a
+b
+b
+g
+g
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(38,1,1) = {"
+a
+a
+a
+a
+a
+a
+b
+b
+g
+b
+b
+b
+b
+b
+b
+b
+g
+g
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(39,1,1) = {"
+a
+a
+a
+a
+a
+b
+b
+g
+g
+e
+b
+b
+g
+g
+K
+g
+g
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(40,1,1) = {"
+a
+a
+a
+a
+a
+b
+i
+E
+g
+g
+g
+g
+g
+b
+b
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(41,1,1) = {"
+a
+a
+a
+a
+b
+b
+e
+g
+l
+g
+e
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(42,1,1) = {"
+a
+a
+a
+a
+b
+e
+g
+g
+i
+i
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(43,1,1) = {"
+a
+a
+a
+a
+r
+b
+b
+b
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
diff --git a/_maps/map_files/RandomZLevels/spacebattle.dmm b/_maps/map_files/RandomZLevels/spacebattle.dmm
index 16acaaacc34..ca68a7bb5b5 100644
--- a/_maps/map_files/RandomZLevels/spacebattle.dmm
+++ b/_maps/map_files/RandomZLevels/spacebattle.dmm
@@ -1270,7 +1270,9 @@
/turf/simulated/floor/plating,
/area/awaymission/spacebattle/cruiser)
"dJ" = (
-/obj/mecha/working/ripley/firefighter,
+/obj/mecha/working/ripley/firefighter{
+ ruin_mecha = 1
+ },
/turf/simulated/floor/plating,
/area/awaymission/spacebattle/cruiser)
"dK" = (
diff --git a/_maps/test_all_maps.dm b/_maps/test_all_maps.dm
index f733f528a24..d169a35f5fc 100644
--- a/_maps/test_all_maps.dm
+++ b/_maps/test_all_maps.dm
@@ -24,12 +24,27 @@
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_blooddrunk1.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_blooddrunk2.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_blooddrunk3.dmm"
+ #include "map_files\RandomRuins\LavaRuins\lavaland_surface_cube.dmm"
+ #include "map_files\RandomRuins\LavaRuins\lavaland_surface_cultaltar.dmm"
+ #include "map_files\RandomRuins\LavaRuins\lavaland_surface_dead_ratvar.dmm"
+ #include "map_files\RandomRuins\LavaRuins\lavaland_surface_envy.dmm"
+ #include "map_files\RandomRuins\LavaRuins\lavaland_surface_fountain_hell.dmm"
+ #include "map_files\RandomRuins\LavaRuins\lavaland_surface_gluttony.dmm"
+ #include "map_files\RandomRuins\LavaRuins\lavaland_surface_greed.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_hermit.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_hierophant.dmm"
+ #include "map_files\RandomRuins\LavaRuins\lavaland_surface_pizza_party.dmm"
+ #include "map_files\RandomRuins\LavaRuins\lavaland_surface_pride.dmm"
+ #include "map_files\RandomRuins\LavaRuins\lavaland_surface_puzzle.dmm"
+ #include "map_files\RandomRuins\LavaRuins\lavaland_surface_random_ripley.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_seed_vault.dmm"
+ #include "map_files\RandomRuins\LavaRuins\lavaland_surface_sloth.dmm"
+ #include "map_files\RandomRuins\LavaRuins\lavaland_surface_survivalpod.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_swarmer_crash.dmm"
#include "map_files\RandomRuins\LavaRuins\lavaland_surface_syndicate_base1.dmm"
-
+ #include "map_files\RandomRuins\LavaRuins\lavaland_surface_ufo_crash.dmm"
+ #include "map_files\RandomRuins\LavaRuins\lavaland_surface_xeno_nest.dmm"
+
// Space Ruins
#include "map_files\RandomRuins\SpaceRuins\abandonedzoo.dmm"
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 3418938d955..319e9beaa1d 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -404,4 +404,8 @@
#define SENSOR_COORDS 3
// Cult summon possibilities
-#define SUMMON_POSSIBILITIES 3
\ No newline at end of file
+#define SUMMON_POSSIBILITIES 3
+
+#define DICE_NOT_RIGGED 1
+#define DICE_BASICALLY_RIGGED 2
+#define DICE_TOTALLY_RIGGED 3
\ No newline at end of file
diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm
index caec5fa8ea6..d98a23a80c2 100644
--- a/code/datums/ruins/lavaland.dm
+++ b/code/datums/ruins/lavaland.dm
@@ -12,6 +12,14 @@
Comes with a rustic wooden bar and suicidal bartender."
suffix = "lavaland_biodome_beach.dmm"
+/datum/map_template/ruin/lavaland/cube
+ name = "The Wishgranter Cube"
+ id = "wishgranter-cube"
+ description = "Nothing good can come from this. Learn from their mistakes and turn around."
+ suffix = "lavaland_surface_cube.dmm"
+ cost = 10
+ allow_duplicates = FALSE
+
/datum/map_template/ruin/lavaland/seed_vault
name = "Seed Vault"
id = "seed-vault"
@@ -46,6 +54,49 @@ datum/map_template/ruin/lavaland/ash_walker
suffix = "lavaland_surface_animal_hospital.dmm"
allow_duplicates = FALSE
+/datum/map_template/ruin/lavaland/sin
+ cost = 10
+ allow_duplicates = FALSE
+
+/datum/map_template/ruin/lavaland/sin/envy
+ name = "Ruin of Envy"
+ id = "envy"
+ description = "When you get what they have, then you'll finally be happy."
+ suffix = "lavaland_surface_envy.dmm"
+
+/datum/map_template/ruin/lavaland/sin/gluttony
+ name = "Ruin of Gluttony"
+ id = "gluttony"
+ description = "If you eat enough, then eating will be all that you do."
+ suffix = "lavaland_surface_gluttony.dmm"
+
+/datum/map_template/ruin/lavaland/sin/greed
+ name = "Ruin of Greed"
+ id = "greed"
+ description = "Sure you don't need magical powers, but you WANT them, and that's what's important."
+ suffix = "lavaland_surface_greed.dmm"
+
+/datum/map_template/ruin/lavaland/sin/pride
+ name = "Ruin of Pride"
+ id = "pride"
+ description = "Wormhole lifebelts are for LOSERS, who you are better than."
+ suffix = "lavaland_surface_pride.dmm"
+
+/datum/map_template/ruin/lavaland/sin/sloth
+ name = "Ruin of Sloth"
+ id = "sloth"
+ description = "..."
+ suffix = "lavaland_surface_sloth.dmm"
+ cost = 0
+
+/datum/map_template/ruin/lavaland/ratvar
+ name = "Dead God"
+ id = "ratvar"
+ description = "Ratvars final resting place."
+ suffix = "lavaland_surface_dead_ratvar.dmm"
+ cost = 0
+ allow_duplicates = FALSE
+
/datum/map_template/ruin/lavaland/hierophant
name = "Hierophant's Arena"
id = "hierophant"
@@ -70,6 +121,51 @@ datum/map_template/ruin/lavaland/ash_walker
name = "Blood-Drunk Miner (Hunter)"
suffix = "lavaland_surface_blooddrunk3.dmm"
+/datum/map_template/ruin/lavaland/ufo_crash
+ name = "UFO Crash"
+ id = "ufo-crash"
+ description = "Turns out that keeping your abductees unconscious is really important. Who knew?"
+ suffix = "lavaland_surface_ufo_crash.dmm"
+ cost = 5
+
+/datum/map_template/ruin/lavaland/xeno_nest
+ name = "Xenomorph Nest"
+ id = "xeno-nest"
+ description = "These xenomorphs got bored of horrifically slaughtering people on space stations, and have settled down on a nice lava filled hellscape to focus on what's really important in life. \
+ Quality memes."
+ suffix = "lavaland_surface_xeno_nest.dmm"
+ cost = 20
+
+/datum/map_template/ruin/lavaland/fountain
+ name = "Fountain Hall"
+ id = "fountain"
+ description = "The fountain has a warning on the side. DANGER: May have undeclared side effects that only become obvious when implemented."
+ suffix = "lavaland_surface_fountain_hall.dmm"
+ cost = 5
+
+/datum/map_template/ruin/lavaland/survivalcapsule
+ name = "Survival Capsule Ruins"
+ id = "survivalcapsule"
+ description = "What was once sanctuary to the common miner, is now their tomb."
+ suffix = "lavaland_surface_survivalpod.dmm"
+ cost = 5
+
+/datum/map_template/ruin/lavaland/pizza
+ name = "Ruined Pizza Party"
+ id = "pizza"
+ description = "Little Timmy's birthday pizza-bash took a turn for the worse when a bluespace anomaly passed by."
+ suffix = "lavaland_surface_pizzaparty.dmm"
+ allow_duplicates = FALSE
+ cost = 5
+
+/datum/map_template/ruin/lavaland/cultaltar
+ name = "Summoning Ritual"
+ id = "cultaltar"
+ description = "A place of vile worship, the scrawling of blood in the middle glowing eerily. A demonic laugh echoes throughout the caverns"
+ suffix = "lavaland_surface_cultaltar.dmm"
+ allow_duplicates = FALSE
+ cost = 10
+
/datum/map_template/ruin/lavaland/hermit
name = "Makeshift Shelter"
id = "hermitcave"
@@ -84,4 +180,19 @@ datum/map_template/ruin/lavaland/ash_walker
description = "A Syndicate shuttle had an unfortunate stowaway..."
suffix = "lavaland_surface_swarmer_crash.dmm"
allow_duplicates = FALSE
- cost = 20
\ No newline at end of file
+ cost = 20
+
+/datum/map_template/ruin/lavaland/miningripley
+ name = "Ripley"
+ id = "ripley"
+ description = "A heavily-damaged mining ripley, property of a very unfortunate miner. You might have to do a bit of work to fix this thing up."
+ suffix = "lavaland_surface_random_ripley.dmm"
+ allow_duplicates = FALSE
+ cost = 5
+
+/datum/map_template/ruin/lavaland/puzzle
+ name = "Ancient Puzzle"
+ id = "puzzle"
+ description = "Mystery to be solved."
+ suffix = "lavaland_surface_puzzle.dmm"
+ cost = 5
\ No newline at end of file
diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm
index 061d8ef91e7..c0d977d0ee9 100644
--- a/code/game/dna/dna2.dm
+++ b/code/game/dna/dna2.dm
@@ -437,4 +437,18 @@ var/global/list/bad_blocks[0]
var/datum/species/S = data["species"]
species = new S
b_type = data["b_type"]
- real_name = data["real_name"]
\ No newline at end of file
+ real_name = data["real_name"]
+
+/datum/dna/proc/transfer_identity(mob/living/carbon/human/destination)
+ if(!istype(destination))
+ return
+
+ // We manually set the species to ensure all proper species change procs are called.
+ destination.set_species(species.type, retain_damage = TRUE)
+ var/datum/dna/new_dna = Clone()
+ new_dna.species = destination.dna.species
+ destination.dna = new_dna
+ destination.dna.species.handle_dna(destination) // Handle DNA has to be re-called as the DNA was changed.
+
+ destination.UpdateAppearance()
+ domutcheck(destination, null, MUTCHK_FORCED)
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index ef2a970adb3..bd15d43e0be 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -494,10 +494,9 @@ var/list/teleport_runes = list()
/obj/effect/rune/narsie/New()
..()
- cultist_name = "Summon [SSticker.cultdat.entity_name]"
+ cultist_name = "Summon [SSticker.cultdat ? SSticker.cultdat.entity_name : "your god"]"
cultist_desc = "tears apart dimensional barriers, calling forth [SSticker.cultdat.entity_title3]. Requires 9 invokers."
-
/obj/effect/rune/narsie/check_icon()
return
diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm
index 7d941a41bde..b12b28709f6 100644
--- a/code/game/gamemodes/wizard/spellbook.dm
+++ b/code/game/gamemodes/wizard/spellbook.dm
@@ -906,3 +906,13 @@
spellname = "sacred flame"
icon_state ="booksacredflame"
desc = "Become one with the flames that burn within... and invite others to do so as well."
+
+/obj/item/spellbook/oneuse/random
+ icon_state = "random_book"
+
+/obj/item/spellbook/oneuse/random/initialize()
+ . = ..()
+ var/static/banned_spells = list(/obj/item/spellbook/oneuse/mime, /obj/item/spellbook/oneuse/mime/fingergun, /obj/item/spellbook/oneuse/mime/fingergun/fake, /obj/item/spellbook/oneuse/mime/greaterwall)
+ var/real_type = pick(subtypesof(/obj/item/spellbook/oneuse) - banned_spells)
+ new real_type(loc)
+ return INITIALIZE_HINT_QDEL
\ No newline at end of file
diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm
index ab7b49062fb..fdf24180022 100644
--- a/code/game/jobs/job/support.dm
+++ b/code/game/jobs/job/support.dm
@@ -193,7 +193,38 @@
backpack = /obj/item/storage/backpack/explorer
satchel = /obj/item/storage/backpack/explorer
+/datum/outfit/job/mining/equipped
+ name = "Shaft Miner"
+ suit = /obj/item/clothing/suit/hooded/explorer
+ mask = /obj/item/clothing/mask/gas/explorer
+ glasses = /obj/item/clothing/glasses/meson
+ suit_store = /obj/item/tank/emergency_oxygen
+ internals_slot = slot_s_store
+ backpack_contents = list(
+ /obj/item/flashlight/seclite=1,\
+ /obj/item/kitchen/knife/combat/survival=1,
+ /obj/item/mining_voucher=1,
+ /obj/item/t_scanner/adv_mining_scanner/lesser=1,
+ /obj/item/gun/energy/kinetic_accelerator=1,\
+ /obj/item/stack/marker_beacon/ten=1
+ )
+
+ backpack = /obj/item/storage/backpack/explorer
+ satchel = /obj/item/storage/backpack/explorer
+
+/datum/outfit/job/miner/equipped/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ ..()
+ if(visualsOnly)
+ return
+ if(istype(H.wear_suit, /obj/item/clothing/suit/hooded))
+ var/obj/item/clothing/suit/hooded/S = H.wear_suit
+ S.ToggleHood()
+
+/datum/outfit/job/miner/equipped/hardsuit
+ name = "Shaft Miner (Equipment + Hardsuit)"
+ suit = /obj/item/clothing/suit/space/hardsuit/mining
+ mask = /obj/item/clothing/mask/breath
//Griff //BS12 EDIT
diff --git a/code/game/machinery/wishgranter.dm b/code/game/machinery/wishgranter.dm
index b2851129a29..c4c4c674294 100644
--- a/code/game/machinery/wishgranter.dm
+++ b/code/game/machinery/wishgranter.dm
@@ -13,26 +13,28 @@
/obj/machinery/wish_granter/attack_hand(mob/living/carbon/user)
. = ..()
+
if(.)
- return
+ return ..()
+
if(charges <= 0)
- to_chat(user, "The Wish Granter lies silent.")
- return
+ to_chat(user, "The Wish Granter lies silent.")
+ return TRUE
else if(!ishuman(user))
- to_chat(user, "You feel a dark stirring inside of the Wish Granter, something you want nothing of. Your instincts are better than any man's.")
+ to_chat(user, "You feel a dark stirring inside of the Wish Granter, something you want nothing of. Your instincts are better than any man's..")
return
else if(is_special_character(user))
- to_chat(user, "Even to a heart as dark as yours, you know nothing good will come of this. Something instinctual makes you pull away.")
+ to_chat(user, "Even to a heart as dark as yours, you know nothing good will come of this. Something instinctual makes you pull away.")
else if(!insisting)
- to_chat(user, "Your first touch makes the Wish Granter stir, listening to you. Are you really sure you want to do this?")
+ to_chat(user, "Your first touch makes the Wish Granter stir, listening to you. Are you really sure you want to do this?")
insisting = TRUE
else
- to_chat(user, "You speak. [pick("I want the station to disappear", "Humanity is corrupt, mankind must be destroyed", "I want to be rich", "I want to rule the world", "I want immortality.")]. The Wish Granter answers.")
- to_chat(user, "Your head pounds for a moment, before your vision clears. You are the avatar of the Wish Granter, and your power is LIMITLESS! And it's all yours. You need to make sure no one can take it from you. No one can know, first.")
+ to_chat(user, "You speak. [pick("I want the station to disappear", "Humanity is corrupt, mankind must be destroyed", "I want to be rich", "I want to rule the world", "I want immortality.")]. The Wish Granter answers.")
+ to_chat(user, "Your head pounds for a moment, before your vision clears. You are the avatar of the Wish Granter, and your power is LIMITLESS! And it's all yours. You need to make sure no one can take it from you. No one can know, first.")
charges--
insisting = FALSE
@@ -46,37 +48,43 @@
var/list/types = list()
/obj/machinery/wish_granter/super/attack_hand(mob/living/carbon/user)
+ . = ..()
+
+ if(.)
+ return ..()
+
if(!ishuman(user))
- to_chat(user, "You feel a dark stirring inside of the Wish Granter, something you want nothing of. Your instincts are better than any man's.")
- return
- else if(is_special_character(user) || jobban_isbanned(user, ROLE_TRAITOR) || jobban_isbanned(user, "Syndicate"))
- to_chat(user, "Something instinctual makes you pull away.")
- return
+ to_chat(user, "You feel a dark stirring inside of the Wish Granter, something you want nothing of. Your instincts are better than any man's.")
+ return TRUE
+
+ if(is_special_character(user) || jobban_isbanned(user, ROLE_TRAITOR) || jobban_isbanned(user, "Syndicate"))
+ to_chat(user, "Something instinctual makes you pull away.")
+ return TRUE
+
+ to_chat(user, "Your touch makes the Wish Granter stir. Are you really sure you want to do this?")
+
+ for(var/supname in GLOB.all_superheroes)
+ types += supname
+
+ var/wish
+ if(types.len == 1)
+ wish = pick(types)
else
-
- to_chat(user, "Your touch makes the Wish Granter stir. Are you really sure you want to do this?")
-
- for(var/supname in GLOB.all_superheroes)
- types += supname
-
- var/wish
- if(types.len == 1)
- wish = pick(types)
- else
- wish = input("You want to become...","Wish") as null|anything in types
+ wish = input("You want to become...", "Wish") as null|anything in types
- if(!src || !wish || user.stat == DEAD || (get_dist(src, user) > 4)) //another check after the input to check if someone already used it, closed it, or if they're dead, or if they ran off
- return
+ if(!wish || user.stat == DEAD || (get_dist(src, user) > 4)) // Another check after the input to check if someone already used it, closed it, or if they're dead, or if they ran off.
+ return
- var/datum/superheroes/S = GLOB.all_superheroes[wish]
- if(S.activated)
- to_chat(user,"There can only be one! Pick something else!")
- return
+ var/datum/superheroes/S = GLOB.all_superheroes[wish]
+ if(S.activated)
+ to_chat(user,"There can only be one! Pick something else!")
+ return
- S.create(user)
- S.activated = TRUE //sets this superhero as taken so we don't have duplicates
- playsound(src.loc, 'sound/effects/bamf.ogg', 50, 1)
- visible_message("The wishgranter fades into mist..")
- add_attack_logs(null, user, "Became [GLOB.all_superheroes[wish]]")
- notify_ghosts("[GLOB.all_superheroes[wish]] has appeared in [get_area(user)].", source = user)
- qdel(src)
+ S.create(user)
+ S.activated = TRUE //sets this superhero as taken so we don't have duplicates
+
+ playsound(src.loc, 'sound/effects/bamf.ogg', 50, 1)
+ visible_message("The wishgranter fades into mist..")
+ add_attack_logs(null, user, "Became [GLOB.all_superheroes[wish]]")
+ notify_ghosts("[GLOB.all_superheroes[wish]] has appeared in [get_area(user)].", source = user)
+ qdel(src)
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index d9d9d5dd261..8f41275167d 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -23,6 +23,7 @@
infra_luminosity = 15 //byond implementation is bugged.
force = 5
armor = list(melee = 20, bullet = 10, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
+ var/ruin_mecha = FALSE //if the mecha starts on a ruin, don't automatically give it a tracking beacon to prevent metagaming.
var/initial_icon = null //Mech type for resetting icon. Only used for reskinning kits (see custom items)
var/can_move = 0 // time of next allowed movement
var/mob/living/carbon/occupant = null
diff --git a/code/game/mecha/working/working.dm b/code/game/mecha/working/working.dm
index e4c001a508a..516b57e898a 100644
--- a/code/game/mecha/working/working.dm
+++ b/code/game/mecha/working/working.dm
@@ -3,4 +3,5 @@
/obj/mecha/working/New()
..()
- trackers += new /obj/item/mecha_parts/mecha_tracking(src)
+ if(!ruin_mecha)
+ trackers += new /obj/item/mecha_parts/mecha_tracking(src)
diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm
index ddce32f68fa..8e7ff018a32 100644
--- a/code/game/objects/effects/effect_system/effects_smoke.dm
+++ b/code/game/objects/effects/effect_system/effects_smoke.dm
@@ -207,4 +207,10 @@
return 1
/datum/effect_system/smoke_spread/sleeping
- effect_type = /obj/effect/particle_effect/smoke/sleeping
\ No newline at end of file
+ effect_type = /obj/effect/particle_effect/smoke/sleeping
+
+/proc/do_smoke(range=0, location=null, smoke_type = /obj/effect/particle_effect/smoke)
+ var/datum/effect_system/smoke_spread/smoke = new
+ smoke.effect_type = smoke_type
+ smoke.set_up(range, location)
+ smoke.start()
diff --git a/code/game/objects/effects/step_triggers.dm b/code/game/objects/effects/step_triggers.dm
index e8cd72b81e9..a9721dd43d0 100644
--- a/code/game/objects/effects/step_triggers.dm
+++ b/code/game/objects/effects/step_triggers.dm
@@ -1,23 +1,43 @@
/* Simple object type, calls a proc when "stepped" on by something */
/obj/effect/step_trigger
- var/affect_ghosts = 0
- var/stopper = 1 // stops throwers
- invisibility = 101 // nope cant see this shit
- anchored = 1
+ var/affect_ghosts = FALSE
+ var/stopper = TRUE // stops throwers
+ var/mobs_only = FALSE
+ invisibility = INVISIBILITY_ABSTRACT // nope cant see this shit
+ anchored = TRUE
/obj/effect/step_trigger/proc/Trigger(var/atom/movable/A)
- return 0
+ return FALSE
-/obj/effect/step_trigger/Crossed(H as mob|obj)
- ..()
+/obj/effect/step_trigger/Crossed(var/H)
+ . = ..()
if(!H)
return
- if(istype(H, /mob/dead/observer) && !affect_ghosts)
+ if(isobserver(H) && !affect_ghosts)
+ return
+ if(!ismob(H) && mobs_only)
return
Trigger(H)
+/obj/effect/step_trigger/singularity_act()
+ return
+/obj/effect/step_trigger/singularity_pull()
+ return
+
+/* Sends a message to mob when triggered*/
+
+/obj/effect/step_trigger/message
+ var/message //the message to give to the mob
+ var/once = 1
+ mobs_only = TRUE
+
+/obj/effect/step_trigger/message/Trigger(mob/M)
+ if(M.client)
+ to_chat(M, "[message]")
+ if(once)
+ qdel(src)
/* Tosses things in a certain direction */
@@ -30,57 +50,57 @@
var/nostop = 0 // if 1: will only be stopped by teleporters
var/list/affecting = list()
- Trigger(var/atom/A)
- if(!A || !istype(A, /atom/movable))
+/obj/effect/step_trigger/thrower/Trigger(atom/A)
+ if(!A || !ismovableatom(A))
+ return
+ var/atom/movable/AM = A
+ var/curtiles = 0
+ var/stopthrow = 0
+ for(var/obj/effect/step_trigger/thrower/T in orange(2, src))
+ if(AM in T.affecting)
return
- var/atom/movable/AM = A
- var/curtiles = 0
- var/stopthrow = 0
- for(var/obj/effect/step_trigger/thrower/T in orange(2, src))
- if(AM in T.affecting)
- return
- if(ismob(AM))
- var/mob/M = AM
- if(immobilize)
- M.canmove = 0
+ if(isliving(AM))
+ var/mob/living/M = AM
+ if(immobilize)
+ M.canmove = FALSE
- affecting.Add(AM)
- while(AM && !stopthrow)
- if(tiles)
- if(curtiles >= tiles)
- break
- if(AM.z != src.z)
+ affecting.Add(AM)
+ while(AM && !stopthrow)
+ if(tiles)
+ if(curtiles >= tiles)
break
+ if(AM.z != src.z)
+ break
- curtiles++
+ curtiles++
- sleep(speed)
+ sleep(speed)
- // Calculate if we should stop the process
- if(!nostop)
- for(var/obj/effect/step_trigger/T in get_step(AM, direction))
- if(T.stopper && T != src)
- stopthrow = 1
- else
- for(var/obj/effect/step_trigger/teleporter/T in get_step(AM, direction))
- if(T.stopper)
- stopthrow = 1
+ // Calculate if we should stop the process
+ if(!nostop)
+ for(var/obj/effect/step_trigger/T in get_step(AM, direction))
+ if(T.stopper && T != src)
+ stopthrow = 1
+ else
+ for(var/obj/effect/step_trigger/teleporter/T in get_step(AM, direction))
+ if(T.stopper)
+ stopthrow = 1
- if(AM)
- var/predir = AM.dir
- step(AM, direction)
- if(!facedir)
- AM.dir = predir
+ if(AM)
+ var/predir = AM.dir
+ step(AM, direction)
+ if(!facedir)
+ AM.setDir(predir)
- affecting.Remove(AM)
+ affecting.Remove(AM)
- if(ismob(AM))
- var/mob/M = AM
- if(immobilize)
- M.canmove = 1
+ if(isliving(AM))
+ var/mob/living/M = AM
+ if(immobilize)
+ M.canmove = TRUE
/* Stops things thrown by a thrower, doesn't do anything */
@@ -93,12 +113,11 @@
var/teleport_y = 0
var/teleport_z = 0
- Trigger(var/atom/movable/A)
- if(teleport_x && teleport_y && teleport_z)
+/obj/effect/step_trigger/teleporter/Trigger(atom/movable/A)
+ if(teleport_x && teleport_y && teleport_z)
- A.x = teleport_x
- A.y = teleport_y
- A.z = teleport_z
+ var/turf/T = locate(teleport_x, teleport_y, teleport_z)
+ A.forceMove(T)
/* Random teleporter, teleports atoms to locations ranging from teleport_x - teleport_x_offset, etc */
@@ -107,11 +126,73 @@
var/teleport_y_offset = 0
var/teleport_z_offset = 0
- Trigger(var/atom/movable/A)
- if(teleport_x && teleport_y && teleport_z)
- if(teleport_x_offset && teleport_y_offset && teleport_z_offset)
+/obj/effect/step_trigger/teleporter/random/Trigger(atom/movable/A)
+ if(teleport_x && teleport_y && teleport_z)
+ if(teleport_x_offset && teleport_y_offset && teleport_z_offset)
- A.x = rand(teleport_x, teleport_x_offset)
- A.y = rand(teleport_y, teleport_y_offset)
- A.z = rand(teleport_z, teleport_z_offset)
+ var/turf/T = locate(rand(teleport_x, teleport_x_offset), rand(teleport_y, teleport_y_offset), rand(teleport_z, teleport_z_offset))
+ if (T)
+ A.forceMove(T)
+/* Fancy teleporter, creates sparks and smokes when used */
+
+/obj/effect/step_trigger/teleport_fancy
+ var/locationx
+ var/locationy
+ var/uses = 1 //0 for infinite uses
+ var/entersparks = 0
+ var/exitsparks = 0
+ var/entersmoke = 0
+ var/exitsmoke = 0
+
+/obj/effect/step_trigger/teleport_fancy/Trigger(mob/M)
+ var/dest = locate(locationx, locationy, z)
+ M.Move(dest)
+
+ if(entersparks)
+ var/datum/effect_system/spark_spread/s = new
+ s.set_up(4, 1, src)
+ s.start()
+ if(exitsparks)
+ var/datum/effect_system/spark_spread/s = new
+ s.set_up(4, 1, dest)
+ s.start()
+
+ if(entersmoke)
+ var/datum/effect_system/smoke_spread/s = new
+ s.set_up(4, 1, src, 0)
+ s.start()
+ if(exitsmoke)
+ var/datum/effect_system/smoke_spread/s = new
+ s.set_up(4, 1, dest, 0)
+ s.start()
+
+ uses--
+ if(uses == 0)
+ qdel(src)
+
+/* Simple sound player, Mapper friendly! */
+
+/obj/effect/step_trigger/sound_effect
+ var/sound //eg. path to the sound, inside '' eg: 'growl.ogg'
+ var/volume = 100
+ var/freq_vary = 1 //Should the frequency of the sound vary?
+ var/extra_range = 0 // eg World.view = 7, extra_range = 1, 7+1 = 8, 8 turfs radius
+ var/happens_once = 0
+ var/triggerer_only = 0 //Whether the triggerer is the only person who hears this
+
+
+/obj/effect/step_trigger/sound_effect/Trigger(atom/movable/A)
+ var/turf/T = get_turf(A)
+
+ if(!T)
+ return
+
+ if(triggerer_only && ismob(A))
+ var/mob/B = A
+ B.playsound_local(T, sound, volume, freq_vary)
+ else
+ playsound(T, sound, volume, freq_vary, extra_range)
+
+ if(happens_once)
+ qdel(src)
\ No newline at end of file
diff --git a/code/game/objects/effects/temporary_visuals/clockcult.dm b/code/game/objects/effects/temporary_visuals/clockcult.dm
index f6b654ccbbe..1dc126faa6c 100644
--- a/code/game/objects/effects/temporary_visuals/clockcult.dm
+++ b/code/game/objects/effects/temporary_visuals/clockcult.dm
@@ -6,6 +6,10 @@
randomdir = 0
layer = ABOVE_NORMAL_TURF_LAYER
+/obj/effect/temp_visual/ratvar/door
+ icon_state = "ratvardoorglow"
+ layer = CLOSED_DOOR_LAYER //above closed doors
+
/obj/effect/temp_visual/ratvar/door/window
icon_state = "ratvarwindoorglow"
layer = ABOVE_WINDOW_LAYER
@@ -16,9 +20,27 @@
/obj/effect/temp_visual/ratvar/beam/grille
layer = BELOW_OBJ_LAYER
+/obj/effect/temp_visual/ratvar/beam/itemconsume
+ layer = HIGH_OBJ_LAYER
+
+/obj/effect/temp_visual/ratvar/beam/falsewall
+ layer = OBJ_LAYER
+
+/obj/effect/temp_visual/ratvar/beam/catwalk
+ layer = LATTICE_LAYER
+
+/obj/effect/temp_visual/ratvar/wall
+ icon_state = "ratvarwallglow"
+
+/obj/effect/temp_visual/ratvar/wall/false
+ layer = OBJ_LAYER
+
/obj/effect/temp_visual/ratvar/floor
icon_state = "ratvarfloorglow"
+/obj/effect/temp_visual/ratvar/floor/catwalk
+ layer = LATTICE_LAYER
+
/obj/effect/temp_visual/ratvar/window
icon_state = "ratvarwindowglow"
layer = ABOVE_OBJ_LAYER
@@ -26,6 +48,10 @@
/obj/effect/temp_visual/ratvar/window/single
icon_state = "ratvarwindowglow_s"
+/obj/effect/temp_visual/ratvar/gear
+ icon_state = "ratvargearglow"
+ layer = BELOW_OBJ_LAYER
+
/obj/effect/temp_visual/ratvar/grille
icon_state = "ratvargrilleglow"
layer = BELOW_OBJ_LAYER
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index 94f195e9c20..d496348f0e8 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -333,10 +333,13 @@ var/global/list/datum/stack_recipe/cult = list ( \
* Brass
*/
var/global/list/datum/stack_recipe/brass_recipes = list (\
+ new/datum/stack_recipe("wall gear", /obj/structure/clockwork/wall_gear, 3, time = 10, one_per_turf = TRUE, on_floor = TRUE), \
+ null,
new/datum/stack_recipe/window("brass windoor", /obj/machinery/door/window/clockwork, 2, time = 30, on_floor = TRUE, window_checks = TRUE), \
null,
new/datum/stack_recipe/window("directional brass window", /obj/structure/window/reinforced/clockwork, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe/window("fulltile brass window", /obj/structure/window/reinforced/clockwork/fulltile, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \
+ new/datum/stack_recipe("brass chair", /obj/structure/chair/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE), \
)
diff --git a/code/game/objects/items/weapons/dice.dm b/code/game/objects/items/weapons/dice.dm
index 40fc1bf7d56..084dac30a60 100644
--- a/code/game/objects/items/weapons/dice.dm
+++ b/code/game/objects/items/weapons/dice.dm
@@ -25,20 +25,34 @@
if(special_die == "100")
new /obj/item/dice/d100(src)
+/obj/item/storage/pill_bottle/dice/suicide_act(mob/user)
+ user.visible_message("[user] is gambling with death! It looks like [user.p_theyre()] trying to commit suicide!")
+ return (OXYLOSS)
+
/obj/item/dice //depreciated d6, use /obj/item/dice/d6 if you actually want a d6
name = "die"
desc = "A die with six sides. Basic and servicable."
icon = 'icons/obj/dice.dmi'
icon_state = "d6"
w_class = WEIGHT_CLASS_TINY
+
var/sides = 6
var/result = null
var/list/special_faces = list() //entries should match up to sides var if used
-/obj/item/dice/New()
- result = rand(1, sides)
+ var/rigged = DICE_NOT_RIGGED
+ var/rigged_value
+
+/obj/item/dice/Initialize(mapload)
+ . = ..()
+ if(!result)
+ result = roll(sides)
update_icon()
+/obj/item/dice/suicide_act(mob/user)
+ user.visible_message("[user] is gambling with death! It looks like [user.p_theyre()] trying to commit suicide!")
+ return (OXYLOSS)
+
/obj/item/dice/d1
name = "d1"
desc = "A die with one side. Deterministic!"
@@ -117,11 +131,19 @@
. = ..()
/obj/item/dice/proc/diceroll(mob/user)
- result = rand(1, sides)
- var/fake_result = rand(1, sides)//Daredevil isn't as good as he used to be
+ result = roll(sides)
+ if(rigged != DICE_NOT_RIGGED && result != rigged_value)
+ if(rigged == DICE_BASICALLY_RIGGED && prob(Clamp(1/(sides - 1) * 100, 25, 80)))
+ result = rigged_value
+ else if(rigged == DICE_TOTALLY_RIGGED)
+ result = rigged_value
+
+ . = result
+
+ var/fake_result = roll(sides)//Daredevil isn't as good as he used to be
var/comment = ""
if(sides == 20 && result == 20)
- comment = "Nat 20!"
+ comment = "NAT 20!"
else if(sides == 20 && result == 1)
comment = "Ouch, bad luck."
update_icon()
@@ -130,16 +152,18 @@
if(special_faces.len == sides)
result = special_faces[result]
if(user != null) //Dice was rolled in someone's hand
- user.visible_message("[user] has thrown [src]. It lands on [result]. [comment]", \
+ user.visible_message("[user] has thrown [src]. It lands on [result]. [comment]", \
"You throw [src]. It lands on [result]. [comment]", \
"You hear [src] rolling, it sounds like a [fake_result].")
- else if(!throwing) //Dice was thrown and is coming to rest
+ else if(!src.throwing) //Dice was thrown and is coming to rest
visible_message("[src] rolls to a stop, landing on [result]. [comment]")
/obj/item/dice/d20/e20/diceroll(mob/user as mob, thrown)
if(triggered)
return
- ..()
+
+ . = ..()
+
if(result == 1)
to_chat(user, "Rocks fall, you die.")
user.gib()
@@ -166,7 +190,7 @@
/obj/item/dice/update_icon()
overlays.Cut()
- overlays += "[src.icon_state][src.result]"
+ overlays += "[icon_state][result]"
/obj/item/storage/box/dice
name = "Box of dice"
diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm
index d23f4c9d606..bf13a05f691 100644
--- a/code/game/objects/structures/aliens.dm
+++ b/code/game/objects/structures/aliens.dm
@@ -235,14 +235,22 @@
var/status = GROWING //can be GROWING, GROWN or BURST; all mutually exclusive
layer = MOB_LAYER
+/obj/structure/alien/egg/grown
+ status = GROWN
+ icon_state = "egg"
+
+/obj/structure/alien/egg/burst
+ status = BURST
+ icon_state = "egg_hatched"
/obj/structure/alien/egg/New()
new /obj/item/clothing/mask/facehugger(src)
..()
- spawn(rand(MIN_GROWTH_TIME, MAX_GROWTH_TIME))
- Grow()
if(status == BURST)
obj_integrity = integrity_failure
+ else if(status != GROWN)
+ spawn(rand(MIN_GROWTH_TIME, MAX_GROWTH_TIME))
+ Grow()
/obj/structure/alien/egg/attack_alien(mob/living/carbon/alien/user)
return attack_hand(user)
diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm
index 9b777d45b58..4a70729d7e9 100644
--- a/code/game/objects/structures/false_walls.dm
+++ b/code/game/objects/structures/false_walls.dm
@@ -9,19 +9,26 @@
/obj/structure/falsewall
name = "wall"
desc = "A huge chunk of metal used to seperate rooms."
- anchored = 1
+ anchored = TRUE
icon = 'icons/turf/walls/wall.dmi'
icon_state = "wall"
- var/mineral = "metal"
- var/walltype = "metal"
- var/opening = 0
- density = 1
- opacity = 1
+
+ var/mineral = /obj/item/stack/sheet/metal
+ var/mineral_amount = 2
+ var/walltype = /turf/simulated/wall
+ var/girder_type = /obj/structure/girder/displaced
+ var/opening = FALSE
+
+ density = TRUE
+ opacity = TRUE
+
+ can_deconstruct = TRUE
canSmoothWith = list(
/turf/simulated/wall,
/turf/simulated/wall/r_wall,
/obj/structure/falsewall,
+ /obj/structure/falsewall/brass,
/obj/structure/falsewall/reinforced, // WHY DO WE SMOOTH WITH FALSE R-WALLS WHEN WE DON'T SMOOTH WITH REAL R-WALLS. //because we do smooth with real r-walls now
/turf/simulated/wall/rust,
/turf/simulated/wall/r_wall/rust)
@@ -31,6 +38,10 @@
..()
air_update_turf(1)
+/obj/structure/falsewall/ratvar_act()
+ new /obj/structure/falsewall/brass(loc)
+ qdel(src)
+
/obj/structure/falsewall/Destroy()
density = 0
air_update_turf(1)
@@ -124,18 +135,11 @@
/obj/structure/falsewall/proc/dismantle(mob/user)
user.visible_message("[user] dismantles the false wall.", "You dismantle the false wall.")
- new /obj/structure/girder/displaced(loc)
- if(mineral == "metal")
- if(istype(src, /obj/structure/falsewall/reinforced))
- new /obj/item/stack/sheet/plasteel(loc, 2)
- else
- new /obj/item/stack/sheet/metal(loc, 2)
- else if(mineral == "wood")
- new/obj/item/stack/sheet/wood(loc, 2)
- else
- var/P = text2path("/obj/item/stack/sheet/mineral/[mineral]")
- new P(loc)
- new P(loc)
+ if(can_deconstruct)
+ new girder_type(loc)
+ if(mineral_amount)
+ for(var/i in 1 to mineral_amount)
+ new mineral(loc)
playsound(src, 'sound/items/welder.ogg', 100, 1)
qdel(src)
@@ -148,7 +152,8 @@
desc = "A huge chunk of reinforced metal used to seperate rooms."
icon = 'icons/turf/walls/reinforced_wall.dmi'
icon_state = "r_wall"
- walltype = "rwall"
+ walltype = /turf/simulated/wall/r_wall
+ mineral = /obj/item/stack/sheet/plasteel
/obj/structure/falsewall/reinforced/ChangeToWall(delete = 1)
var/turf/T = get_turf(src)
@@ -166,8 +171,8 @@
desc = "A wall with uranium plating. This is probably a bad idea."
icon = 'icons/turf/walls/uranium_wall.dmi'
icon_state = "uranium"
- mineral = "uranium"
- walltype = "uranium"
+ mineral = /obj/item/stack/sheet/mineral/uranium
+ walltype = /turf/simulated/wall/mineral/uranium
var/active = null
var/last_event = 0
canSmoothWith = list(/obj/structure/falsewall/uranium, /turf/simulated/wall/mineral/uranium)
@@ -201,8 +206,8 @@
desc = "A wall with gold plating. Swag!"
icon = 'icons/turf/walls/gold_wall.dmi'
icon_state = "gold"
- mineral = "gold"
- walltype = "gold"
+ mineral = /obj/item/stack/sheet/mineral/gold
+ walltype = /turf/simulated/wall/mineral/gold
canSmoothWith = list(/obj/structure/falsewall/gold, /turf/simulated/wall/mineral/gold)
/obj/structure/falsewall/silver
@@ -210,8 +215,8 @@
desc = "A wall with silver plating. Shiny."
icon = 'icons/turf/walls/silver_wall.dmi'
icon_state = "silver"
- mineral = "silver"
- walltype = "silver"
+ mineral = /obj/item/stack/sheet/mineral/silver
+ walltype = /turf/simulated/wall/mineral/silver
canSmoothWith = list(/obj/structure/falsewall/silver, /turf/simulated/wall/mineral/silver)
/obj/structure/falsewall/diamond
@@ -219,8 +224,8 @@
desc = "A wall with diamond plating. You monster."
icon = 'icons/turf/walls/diamond_wall.dmi'
icon_state = "diamond"
- mineral = "diamond"
- walltype = "diamond"
+ mineral = /obj/item/stack/sheet/mineral/diamond
+ walltype = /turf/simulated/wall/mineral/diamond
canSmoothWith = list(/obj/structure/falsewall/diamond, /turf/simulated/wall/mineral/diamond)
@@ -229,18 +234,18 @@
desc = "A wall with plasma plating. This is definately a bad idea."
icon = 'icons/turf/walls/plasma_wall.dmi'
icon_state = "plasma"
- mineral = "plasma"
- walltype = "plasma"
+ mineral = /obj/item/stack/sheet/mineral/plasma
+ walltype = /turf/simulated/wall/mineral/plasma
canSmoothWith = list(/obj/structure/falsewall/plasma, /turf/simulated/wall/mineral/plasma, /turf/simulated/wall/mineral/alien)
/obj/structure/falsewall/plasma/attackby(obj/item/W, mob/user, params)
if(is_hot(W) > 300)
- message_admins("Plasma falsewall ignited by [key_name_admin(user)] in ([x],[y],[z] - JMP)",0,1)
- log_game("Plasma falsewall ignited by [key_name(user)] in ([x],[y],[z])")
+ message_admins("Plasma falsewall ignited by [key_name_admin(user)] in [ADMIN_VERBOSEJMP(T)]")
+ log_game("Plasma falsewall ignited by [key_name(user)] in [AREACOORD(T)]")
investigate_log("was ignited by [key_name(user)]","atmos")
burnbabyburn()
- return
- ..()
+ else
+ return ..()
/obj/structure/falsewall/plasma/proc/burnbabyburn(user)
playsound(src, 'sound/items/welder.ogg', 100, 1)
@@ -258,8 +263,8 @@
desc = "A strange-looking alien wall."
icon = 'icons/turf/walls/plasma_wall.dmi'
icon_state = "plasma"
- mineral = "alien"
- walltype = "alien"
+ mineral = /obj/item/stack/sheet/mineral/abductor
+ walltype = /turf/simulated/wall/mineral/abductor
canSmoothWith = list(/obj/structure/falsewall/alien, /turf/simulated/wall/mineral/alien)
@@ -268,16 +273,16 @@
desc = "A wall with bananium plating. Honk!"
icon = 'icons/turf/walls/bananium_wall.dmi'
icon_state = "bananium"
- mineral = "clown"
- walltype = "clown"
+ mineral = /obj/item/stack/sheet/mineral/bananium
+ walltype = /turf/simulated/wall/mineral/bananium
canSmoothWith = list(/obj/structure/falsewall/bananium, /turf/simulated/wall/mineral/bananium)
/obj/structure/falsewall/sandstone
name = "sandstone wall"
desc = "A wall with sandstone plating."
icon_state = "sandstone"
- mineral = "sandstone"
- walltype = "sandstone"
+ mineral = /obj/item/stack/sheet/mineral/sandstone
+ walltype = /turf/simulated/wall/mineral/sandstone
canSmoothWith = list(/obj/structure/falsewall/sandstone, /turf/simulated/wall/mineral/sandstone)
/obj/structure/falsewall/wood
@@ -285,8 +290,8 @@
desc = "A wall with wooden plating. Stiff."
icon = 'icons/turf/walls/wood_wall.dmi'
icon_state = "wood"
- mineral = "wood"
- walltype = "wood"
+ mineral = /obj/item/stack/sheet/wood
+ walltype = /turf/simulated/wall/mineral/wood
canSmoothWith = list(/obj/structure/falsewall/wood, /turf/simulated/wall/mineral/wood)
/obj/structure/falsewall/iron
@@ -294,8 +299,9 @@
desc = "A wall with rough metal plating."
icon = 'icons/turf/walls/iron_wall.dmi'
icon_state = "iron"
- mineral = "metal"
- walltype = "iron"
+ mineral = /obj/item/stack/rods
+ mineral_amount = 5
+ walltype = /turf/simulated/wall/mineral/iron
canSmoothWith = list(/obj/structure/falsewall/iron, /turf/simulated/wall/mineral/iron)
/obj/structure/falsewall/abductor
@@ -303,8 +309,8 @@
desc = "A wall with alien alloy plating."
icon = 'icons/turf/walls/abductor_wall.dmi'
icon_state = "abductor"
- mineral = "abductor"
- walltype = "abductor"
+ mineral = /obj/item/stack/sheet/mineral/abductor
+ walltype = /turf/simulated/wall/mineral/abductor
canSmoothWith = list(/obj/structure/falsewall/abductor, /turf/simulated/wall/mineral/abductor)
/obj/structure/falsewall/titanium
@@ -324,3 +330,23 @@
walltype = /turf/simulated/wall/mineral/plastitanium
smooth = SMOOTH_MORE
canSmoothWith = list(/turf/simulated/wall/mineral/plastitanium, /obj/machinery/door/airlock/shuttle, /obj/machinery/door/airlock, /obj/structure/window/full/shuttle, /obj/structure/shuttle/engine/heater)
+
+/obj/structure/falsewall/brass
+ name = "clockwork wall"
+ desc = "A huge chunk of warm metal. The clanging of machinery emanates from within."
+ icon = 'icons/turf/walls/clockwork_wall.dmi'
+ icon_state = "clockwork_wall"
+ resistance_flags = FIRE_PROOF
+ unacidable = TRUE
+ mineral_amount = 1
+ canSmoothWith = list(/obj/effect/clockwork/overlay/wall, /obj/structure/falsewall/brass)
+ girder_type = /obj/structure/clockwork/wall_gear/displaced
+ walltype = /turf/simulated/wall/clockwork
+ mineral = /obj/item/stack/tile/brass
+
+/obj/structure/falsewall/brass/New(loc)
+ ..()
+ var/turf/T = get_turf(src)
+ new /obj/effect/temp_visual/ratvar/wall/false(T)
+ new /obj/effect/temp_visual/ratvar/beam/falsewall(T)
+
diff --git a/code/game/objects/structures/fluff.dm b/code/game/objects/structures/fluff.dm
index 356d52e9d2a..a6a4f699314 100644
--- a/code/game/objects/structures/fluff.dm
+++ b/code/game/objects/structures/fluff.dm
@@ -63,3 +63,19 @@
/obj/structure/fluff/drake_statue/falling //A variety of statue in disrepair; parts are broken off and a gemstone is missing
desc = "A towering basalt sculpture of a drake. Cracks run down its surface and parts of it have fallen off."
icon_state = "drake_statue_falling"
+
+/obj/structure/fluff/divine
+ name = "Miracle"
+ icon = 'icons/obj/hand_of_god_structures.dmi'
+ anchored = TRUE
+ density = TRUE
+
+/obj/structure/fluff/divine/nexus
+ name = "nexus"
+ desc = "It anchors a deity to this world. It radiates an unusual aura. It looks well protected from explosive shock."
+ icon_state = "nexus"
+
+/obj/structure/fluff/divine/conduit
+ name = "conduit"
+ desc = "It allows a deity to extend their reach. Their powers are just as potent near a conduit as a nexus."
+ icon_state = "conduit"
\ No newline at end of file
diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm
index 0e440e12f16..c0d958cd2ae 100644
--- a/code/game/objects/structures/lattice.dm
+++ b/code/game/objects/structures/lattice.dm
@@ -59,6 +59,26 @@
if(current_size >= STAGE_FOUR)
qdel(src)
+/obj/structure/lattice/clockwork
+ name = "cog lattice"
+ desc = "A lightweight support lattice. These hold the Justicar's station together."
+ icon = 'icons/obj/smooth_structures/lattice_clockwork.dmi'
+
+/obj/structure/lattice/clockwork/Initialize(mapload)
+ . = ..()
+ ratvar_act()
+
+/obj/structure/lattice/clockwork/ratvar_act()
+ if((x + y) % 2 != 0)
+ icon = 'icons/obj/smooth_structures/lattice_clockwork_large.dmi'
+ pixel_x = -9
+ pixel_y = -9
+ else
+ icon = 'icons/obj/smooth_structures/lattice_clockwork.dmi'
+ pixel_x = 0
+ pixel_y = 0
+ return TRUE
+
/obj/structure/lattice/catwalk
name = "catwalk"
desc = "A catwalk for easier EVA maneuvering and cable placement."
@@ -82,3 +102,30 @@
for(var/obj/structure/cable/C in T)
C.deconstruct()
..()
+
+/obj/structure/lattice/catwalk/clockwork
+ name = "clockwork catwalk"
+ icon = 'icons/obj/smooth_structures/catwalk_clockwork.dmi'
+ canSmoothWith = list(/obj/structure/lattice,
+ /turf/simulated/floor,
+ /turf/simulated/wall,
+ /obj/structure/falsewall)
+ smooth = SMOOTH_MORE
+
+/obj/structure/lattice/catwalk/clockwork/Initialize(mapload)
+ . = ..()
+ ratvar_act()
+ if(!mapload)
+ new /obj/effect/temp_visual/ratvar/floor/catwalk(loc)
+ new /obj/effect/temp_visual/ratvar/beam/catwalk(loc)
+
+/obj/structure/lattice/catwalk/clockwork/ratvar_act()
+ if((x + y) % 2 != 0)
+ icon = 'icons/obj/smooth_structures/catwalk_clockwork_large.dmi'
+ pixel_x = -9
+ pixel_y = -9
+ else
+ icon = 'icons/obj/smooth_structures/catwalk_clockwork.dmi'
+ pixel_x = 0
+ pixel_y = 0
+ return TRUE
diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm
index d8898a7d671..923fab9e885 100644
--- a/code/game/objects/structures/mirror.dm
+++ b/code/game/objects/structures/mirror.dm
@@ -6,7 +6,6 @@
icon_state = "mirror"
density = 0
anchored = 1
- var/shattered = 0
var/list/ui_users = list()
/obj/structure/mirror/New(turf/T, newdir = SOUTH, building = FALSE)
@@ -23,7 +22,7 @@
pixel_x = 32
/obj/structure/mirror/attack_hand(mob/user)
- if(shattered)
+ if(broken)
return
if(ishuman(user))
@@ -36,9 +35,9 @@
AC.ui_interact(user)
/obj/structure/mirror/proc/shatter()
- if(shattered)
+ if(broken)
return
- shattered = 1
+ broken = TRUE
icon_state = "mirror_broke"
playsound(src, "shatter", 70, 1)
desc = "Oh no, seven years of bad luck!"
@@ -46,7 +45,7 @@
/obj/structure/mirror/bullet_act(obj/item/projectile/Proj)
if(prob(Proj.damage * 2))
- if(!shattered)
+ if(!broken)
shatter()
else
playsound(src, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
@@ -58,7 +57,7 @@
if(isscrewdriver(I))
user.visible_message("[user] begins to unfasten [src].", "You begin to unfasten [src].")
if(do_after(user, 30 * I.toolspeed, target = src))
- if(shattered)
+ if(broken)
user.visible_message("[user] drops the broken shards to the floor.", "You drop the broken shards on the floor.")
new /obj/item/shard(get_turf(user))
else
@@ -68,7 +67,7 @@
return
user.do_attack_animation(src)
- if(shattered)
+ if(broken)
playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
return
@@ -85,7 +84,7 @@
if(islarva(user))
return
user.do_attack_animation(src)
- if(shattered)
+ if(broken)
playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
return
user.visible_message("[user] smashes [src]!")
@@ -100,7 +99,7 @@
if(M.melee_damage_upper <= 0)
return
M.do_attack_animation(src)
- if(shattered)
+ if(broken)
playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
return
user.visible_message("[user] smashes [src]!")
@@ -113,7 +112,7 @@
if(!S.is_adult)
return
user.do_attack_animation(src)
- if(shattered)
+ if(broken)
playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
return
user.visible_message("[user] smashes [src]!")
@@ -136,7 +135,7 @@
icon_state = "magic_mirror"
/obj/structure/mirror/magic/attack_hand(mob/user)
- if(!ishuman(user))
+ if(!ishuman(user) || broken)
return
var/mob/living/carbon/human/H = user
@@ -154,6 +153,9 @@
H.dna.real_name = newname
if(H.mind)
H.mind.name = newname
+
+ if(newname)
+ curse(user)
if("Body")
var/list/race_list = list("Human", "Tajaran", "Skrell", "Unathi", "Diona", "Vulpkanin")
@@ -172,6 +174,7 @@
AC.whitelist = race_list
ui_users[user] = AC
AC.ui_interact(user)
+
if("Voice")
var/voice_choice = input(user, "Perhaps...", "Voice effects") as null|anything in list("Comic Sans", "Wingdings", "Swedish", "Chav")
var/voice_mutation
@@ -192,8 +195,17 @@
H.dna.SetSEState(voice_mutation, TRUE)
genemutcheck(H, voice_mutation, null, MUTCHK_FORCED)
+ if(voice_choice)
+ curse(user)
+
+/obj/structure/mirror/magic/on_ui_close(mob/user)
+ curse(user)
+
/obj/structure/mirror/magic/attackby(obj/item/I, mob/living/user, params)
return
/obj/structure/mirror/magic/shatter()
- return //can't be broken. it's magic, i ain't gotta explain shit
\ No newline at end of file
+ return //can't be broken. it's magic, i ain't gotta explain shit
+
+/obj/structure/mirror/magic/proc/curse(mob/living/user)
+ return
\ No newline at end of file
diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
index 903ee22c683..b9b72c04455 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
@@ -28,6 +28,11 @@
W.setDir(dir)
qdel(src)
+/obj/structure/chair/ratvar_act()
+ var/obj/structure/chair/brass/B = new(get_turf(src))
+ B.setDir(dir)
+ qdel(src)
+
/obj/structure/chair/Move(atom/newloc, direct)
..()
handle_rotation()
@@ -416,3 +421,41 @@
desc = "You sit in this. Either by will or force. Looks REALLY uncomfortable."
icon_state = "chairold"
item_chair = null
+
+// Brass chair
+/obj/structure/chair/brass
+ name = "brass chair"
+ desc = "A spinny chair made of brass. It looks uncomfortable."
+ icon_state = "brass_chair"
+ max_integrity = 150
+ buildstacktype = /obj/item/stack/tile/brass
+ buildstackamount = 1
+ item_chair = null
+ var/turns = 0
+
+/obj/structure/chair/brass/Destroy()
+ STOP_PROCESSING(SSfastprocess, src)
+ . = ..()
+
+/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(!istype(user) || user.incapacitated() || !in_range(src, user))
+ return
+ if(!isprocessing)
+ user.visible_message("[user] spins [src] around, and Ratvarian technology keeps it spinning FOREVER.", \
+ "Automated spinny chairs. The pinnacle of Ratvarian technology.")
+ START_PROCESSING(SSfastprocess, src)
+ else
+ user.visible_message("[user] stops [src]'s uncontrollable spinning.", \
+ "You grab [src] and stop its wild spinning.")
+ STOP_PROCESSING(SSfastprocess, src)
\ No newline at end of file
diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm
index ddf71b96798..5c8f2022189 100644
--- a/code/game/turfs/simulated/floor/misc_floor.dm
+++ b/code/game/turfs/simulated/floor/misc_floor.dm
@@ -111,18 +111,35 @@
/turf/simulated/floor/clockwork
name = "clockwork floor"
desc = "Tightly-pressed brass tiles. They emit minute vibration."
- icon_state = "clockwork_floor"
+ icon_state = "plating"
+ baseturf = /turf/simulated/floor/clockwork
+ var/dropped_brass
+ var/uses_overlay = TRUE
+ var/obj/effect/clockwork/overlay/floor/realappearence
-/turf/simulated/floor/clockwork/New()
- ..()
- new /obj/effect/temp_visual/ratvar/floor(src)
- new /obj/effect/temp_visual/ratvar/beam(src)
+/turf/simulated/floor/clockwork/Initialize(mapload)
+ . = ..()
+ if(uses_overlay)
+ new /obj/effect/temp_visual/ratvar/floor(src)
+ new /obj/effect/temp_visual/ratvar/beam(src)
+ realappearence = new /obj/effect/clockwork/overlay/floor(src)
+ realappearence.linked = src
+
+/turf/simulated/floor/clockwork/Destroy()
+ if(uses_overlay && realappearence)
+ QDEL_NULL(realappearence)
+ return ..()
+
+/turf/simulated/floor/clockwork/ReplaceWithLattice()
+ . = ..()
+ for(var/obj/structure/lattice/L in src)
+ L.ratvar_act()
/turf/simulated/floor/clockwork/attackby(obj/item/I, mob/living/user, params)
if(iscrowbar(I))
user.visible_message("[user] begins slowly prying up [src]...", "You begin painstakingly prying up [src]...")
playsound(src, I.usesound, 20, 1)
- if(!do_after(user, 70*I.toolspeed, target = src))
+ if(!do_after(user, 70 * I.toolspeed, target = src))
return 0
user.visible_message("[user] pries up [src]!", "You pry up [src]!")
playsound(src, I.usesound, 80, 1)
@@ -131,7 +148,11 @@
return ..()
/turf/simulated/floor/clockwork/make_plating()
- new /obj/item/stack/tile/brass(src)
+ if(!dropped_brass)
+ new /obj/item/stack/tile/brass(src)
+ dropped_brass = TRUE
+ if(baseturf == type)
+ return
return ..()
/turf/simulated/floor/clockwork/narsie_act()
@@ -140,3 +161,12 @@
var/previouscolor = color
color = "#960000"
animate(src, color = previouscolor, time = 8)
+ addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8)
+
+/turf/simulated/floor/clockwork/reebe
+ name = "cogplate"
+ desc = "Warm brass plating. You can feel it gently vibrating, as if machinery is on the other side."
+ icon_state = "reebe"
+ baseturf = /turf/simulated/floor/clockwork/reebe
+ uses_overlay = FALSE
+ planetary_atmos = TRUE
diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm
index ee53cd0ca35..c568a9801a6 100644
--- a/code/game/turfs/simulated/floor/plating.dm
+++ b/code/game/turfs/simulated/floor/plating.dm
@@ -17,6 +17,16 @@
icon_plating = icon_state
update_icon()
+/turf/simulated/floor/plating/damaged/New()
+ ..()
+ icon_state = icon_plating
+ break_tile()
+
+/turf/simulated/floor/plating/burnt/New()
+ ..()
+ icon_state = icon_plating
+ burn_tile()
+
/turf/simulated/floor/plating/update_icon()
if(!..())
return
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index 8163bc75acc..5a8f842307e 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -22,6 +22,7 @@
heat_capacity = 312500 //a little over 5 cm thick , 312500 for 1 m by 2.5 m by 0.25 m plasteel wall
var/hardness = 40 //lower numbers are harder. Used to determine the probability of a hulk smashing through.
+ var/slicing_duration = 100
var/engraving //engraving on the wall
var/engraving_quality
@@ -340,7 +341,7 @@
to_chat(user, "You begin slicing through the outer plating.")
playsound(src, WT.usesound, 100, 1)
- if(do_after(user, 100 * WT.toolspeed, target = src) && WT && WT.isOn())
+ if(do_after(user, slicing_duration * WT.toolspeed, target = src) && WT && WT.isOn())
to_chat(user, "You remove the outer plating.")
dismantle_wall()
else
diff --git a/code/game/turfs/simulated/walls_indestructible.dm b/code/game/turfs/simulated/walls_indestructible.dm
index 0357578c762..e25992a2555 100644
--- a/code/game/turfs/simulated/walls_indestructible.dm
+++ b/code/game/turfs/simulated/walls_indestructible.dm
@@ -69,4 +69,8 @@
desc = "A wall made out of smooth, cold stone."
icon = 'icons/turf/walls/hierophant_wall.dmi'
icon_state = "hierophant"
- smooth = SMOOTH_TRUE
\ No newline at end of file
+ smooth = SMOOTH_TRUE
+
+/turf/simulated/wall/indestructible/uranium
+ icon = 'icons/turf/walls/uranium_wall.dmi'
+ icon_state = "uranium"
\ No newline at end of file
diff --git a/code/game/turfs/simulated/walls_misc.dm b/code/game/turfs/simulated/walls_misc.dm
index 9b4cba19f0a..b2d6b40c123 100644
--- a/code/game/turfs/simulated/walls_misc.dm
+++ b/code/game/turfs/simulated/walls_misc.dm
@@ -50,3 +50,100 @@
desc = "A huge chunk of reinforced metal used to seperate rooms. It seems to have additional plating to protect against heat."
icon = 'icons/turf/walls/coated_reinforced_wall.dmi'
max_temperature = INFINITY
+
+//Clockwork walls
+/turf/simulated/wall/clockwork
+ name = "clockwork wall"
+ desc = "A huge chunk of warm metal. The clanging of machinery emanates from within."
+ explosion_block = 2
+ hardness = 10
+ slicing_duration = 80
+ sheet_type = /obj/item/stack/tile/brass
+ sheet_amount = 1
+ girder_type = /obj/structure/clockwork/wall_gear
+ baseturf = /turf/simulated/floor/clockwork/reebe
+ var/heated
+ var/obj/effect/clockwork/overlay/wall/realappearance
+
+/turf/simulated/wall/clockwork/Initialize()
+ . = ..()
+ new /obj/effect/temp_visual/ratvar/wall(src)
+ new /obj/effect/temp_visual/ratvar/beam(src)
+ realappearance = new /obj/effect/clockwork/overlay/wall(src)
+ realappearance.linked = src
+
+/turf/simulated/wall/clockwork/Destroy()
+ if(realappearance)
+ qdel(realappearance)
+ realappearance = null
+
+ return ..()
+
+/turf/simulated/wall/clockwork/ReplaceWithLattice()
+ ..()
+ for(var/obj/structure/lattice/L in src)
+ L.ratvar_act()
+
+/turf/simulated/wall/clockwork/narsie_act()
+ ..()
+ if(istype(src, /turf/simulated/wall/clockwork)) //if we haven't changed type
+ var/previouscolor = color
+ color = "#960000"
+ animate(src, color = previouscolor, time = 8)
+ addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8)
+
+/turf/simulated/wall/clockwork/dismantle_wall(devastated=0, explode=0)
+ if(devastated)
+ devastate_wall()
+ ChangeTurf(baseturf)
+ else
+ playsound(src, 'sound/items/welder.ogg', 100, 1)
+ var/newgirder = break_wall()
+ if(newgirder) //maybe we want a gear!
+ transfer_fingerprints_to(newgirder)
+ ChangeTurf(baseturf)
+
+ for(var/obj/O in src) //Eject contents!
+ if(istype(O, /obj/structure/sign/poster))
+ var/obj/structure/sign/poster/P = O
+ P.roll_and_drop(src)
+ else
+ O.forceMove(src)
+
+/turf/simulated/wall/clockwork/devastate_wall()
+ for(var/i in 1 to 2)
+ new/obj/item/clockwork/alloy_shards/large(src)
+ for(var/i in 1 to 2)
+ new/obj/item/clockwork/alloy_shards/medium(src)
+ for(var/i in 1 to 3)
+ new/obj/item/clockwork/alloy_shards/small(src)
+
+/turf/simulated/wall/clockwork/attack_hulk(mob/living/user, does_attack_animation = 0)
+ ..()
+ if(heated)
+ to_chat(user, "The wall is searing hot to the touch!")
+ user.adjustFireLoss(5)
+ playsound(src, 'sound/machines/fryer/deep_fryer_emerge.ogg', 50, TRUE)
+
+/turf/simulated/wall/clockwork/mech_melee_attack(obj/mecha/M)
+ ..()
+ if(heated)
+ to_chat(M.occupant, "The wall's intense heat completely reflects your [M.name]'s attack!")
+ M.take_damage(20, BURN)
+
+/turf/simulated/wall/clockwork/proc/turn_up_the_heat()
+ if(!heated)
+ name = "superheated [name]"
+ visible_message("[src] sizzles with heat!")
+ playsound(src, 'sound/machines/fryer/deep_fryer_emerge.ogg', 50, TRUE)
+ heated = TRUE
+ hardness = -100 //Lower numbers are tougher, so this makes the wall essentially impervious to smashing
+ slicing_duration = 150
+ animate(realappearance, color = "#FFC3C3", time = 5)
+ else
+ name = initial(name)
+ visible_message("[src] cools down.")
+ heated = FALSE
+ hardness = initial(hardness)
+ slicing_duration = initial(slicing_duration)
+ animate(realappearance, color = initial(realappearance.color), time = 25)
diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm
index 9a74edfdc62..92a6a2b1d86 100644
--- a/code/modules/awaymissions/corpse.dm
+++ b/code/modules/awaymissions/corpse.dm
@@ -432,6 +432,8 @@
l_pocket = /obj/item/reagent_containers/food/pill/patch/styptic
r_pocket = /obj/item/flashlight/seclite
+/obj/effect/mob_spawn/human/miner/explorer
+ outfit = /datum/outfit/job/mining/equipped
/obj/effect/mob_spawn/human/bartender
name = "Space Bartender"
diff --git a/code/modules/awaymissions/mission_code/academy.dm b/code/modules/awaymissions/mission_code/academy.dm
index 2c764443e72..86e5dd045a0 100644
--- a/code/modules/awaymissions/mission_code/academy.dm
+++ b/code/modules/awaymissions/mission_code/academy.dm
@@ -36,9 +36,220 @@
if(prob(1))
mezzer()
-
/obj/item/clothing/glasses/meson/truesight
name = "The Lens of Truesight"
desc = "I can see forever!"
icon_state = "monocle"
- item_state = "headset"
\ No newline at end of file
+ item_state = "headset"
+
+// Die of Fate
+/obj/item/dice/d20/fate
+ name = "\improper Die of Fate"
+ desc = "A die with twenty sides. You can feel unearthly energies radiating from it. Using this might be VERY risky."
+ icon_state = "d20"
+ var/reusable = TRUE
+ var/used = FALSE
+
+/obj/item/dice/d20/fate/stealth
+ name = "d20"
+ desc = "A die with twenty sides. The preferred die to throw at the GM."
+
+/obj/item/dice/d20/fate/one_use
+ reusable = FALSE
+
+/obj/item/dice/d20/fate/one_use/stealth
+ name = "d20"
+ desc = "A die with twenty sides. The preferred die to throw at the GM."
+
+/obj/item/dice/d20/fate/cursed
+ name = "cursed Die of Fate"
+ desc = "A die with twenty sides. You feel that rolling this is a REALLY bad idea."
+ color = "#00BB00"
+
+ rigged = DICE_TOTALLY_RIGGED
+ rigged_value = 1
+
+/obj/item/dice/d20/fate/diceroll(mob/user)
+ . = ..()
+ if(!used)
+ if(!ishuman(user) || !user.mind || (user.mind in SSticker.mode.wizards))
+ to_chat(user, "You feel the magic of the dice is restricted to ordinary humans!")
+ return
+
+ if(!reusable)
+ used = TRUE
+
+ var/turf/T = get_turf(src)
+ T.visible_message("[src] flares briefly.")
+
+ addtimer(CALLBACK(src, .proc/effect, user, .), 1 SECONDS)
+
+/obj/item/dice/d20/fate/equipped(mob/user, slot)
+ if(!ishuman(user) || !user.mind || (user.mind in SSticker.mode.wizards))
+ to_chat(user, "You feel the magic of the dice is restricted to ordinary humans! You should leave it alone.")
+ forceMove(get_turf(user))
+
+/obj/item/dice/d20/fate/proc/effect(var/mob/living/carbon/human/user, roll)
+ var/turf/T = get_turf(src)
+ switch(roll)
+ if(1)
+ //Dust
+ T.visible_message("[user] turns to dust!")
+ user.dust()
+ if(2)
+ //Death
+ T.visible_message("[user] suddenly dies!")
+ user.death()
+ if(3)
+ //Swarm of creatures
+ T.visible_message("A swarm of creatures surround [user]!")
+ for(var/direction in alldirs)
+ new /mob/living/simple_animal/hostile/netherworld(get_step(get_turf(user),direction))
+ if(4)
+ //Destroy Equipment
+ T.visible_message("Everything [user] is holding and wearing disappears!")
+ for(var/obj/item/I in user)
+ if(istype(I, /obj/item/implant))
+ continue
+ qdel(I)
+ if(5)
+ //Monkeying
+ T.visible_message("[user] transforms into a monkey!")
+ user.monkeyize()
+ if(6)
+ //Cut speed
+ T.visible_message("[user] starts moving slower!")
+ var/datum/species/S = user.dna.species
+ S.slowdown += 1
+ if(7)
+ //Throw
+ T.visible_message("Unseen forces throw [user]!")
+ user.Stun(60)
+ user.adjustBruteLoss(50)
+ var/throw_dir = cardinal
+ var/atom/throw_target = get_edge_target_turf(user, throw_dir)
+ user.throw_at(throw_target, 200, 4)
+ if(8)
+ //Fueltank Explosion
+ T.visible_message("An explosion bursts into existence around [user]!")
+ explosion(get_turf(user),-1,0,2, flame_range = 2)
+ if(9)
+ //Cold
+ var/datum/disease/D = new /datum/disease/cold()
+ T.visible_message("[user] looks a little under the weather!")
+ user.ForceContractDisease(D)
+ if(10)
+ //Nothing
+ T.visible_message("Nothing seems to happen.")
+ if(11)
+ //Cookie
+ T.visible_message("A cookie appears out of thin air!")
+ var/obj/item/reagent_containers/food/snacks/cookie/C = new(drop_location())
+ do_smoke(0, drop_location())
+ C.name = "Cookie of Fate"
+ if(12)
+ //Healing
+ T.visible_message("[user] looks very healthy!")
+ user.revive(full_heal = 1, admin_revive = 1)
+ if(13)
+ //Mad Dosh
+ T.visible_message("Mad dosh shoots out of [src]!")
+ var/turf/Start = get_turf(src)
+ for(var/direction in alldirs)
+ var/turf/dirturf = get_step(Start,direction)
+ if(rand(0,1))
+ new /obj/item/stack/spacecash/c1000(dirturf)
+ else
+ var/obj/item/storage/bag/money/M = new(dirturf)
+ for(var/i in 1 to rand(5,50))
+ new /obj/item/coin/gold(M)
+ if(14)
+ //Free Gun
+ T.visible_message("An impressive gun appears!")
+ do_smoke(0, drop_location())
+ new /obj/item/gun/projectile/revolver/mateba(drop_location())
+ if(15)
+ //Random One-use spellbook
+ T.visible_message("A magical looking book drops to the floor!")
+ do_smoke(0, drop_location())
+ new /obj/item/spellbook/oneuse/random(drop_location())
+ if(16)
+ //Servant & Servant Summon
+ T.visible_message("A Dice Servant appears in a cloud of smoke!")
+ var/mob/living/carbon/human/H = new(drop_location())
+ do_smoke(0, drop_location())
+
+ H.equipOutfit(/datum/outfit/butler)
+ var/datum/mind/servant_mind = new /datum/mind()
+ var/datum/objective/O = new
+ O.owner = servant_mind
+ O.target = H.mind
+ O.explanation_text = "Serve [user.real_name]."
+ servant_mind.objectives += O
+ servant_mind.transfer_to(H)
+
+ var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as the servant of [user.real_name]?", ROLE_WIZARD, poll_time = 50)
+ if(LAZYLEN(candidates))
+ var/mob/dead/observer/C = pick(candidates)
+ message_admins("[ADMIN_LOOKUPFLW(C)] was spawned as Dice Servant")
+ H.key = C.key
+
+ var/obj/effect/proc_holder/spell/targeted/summonmob/S = new
+ S.target_mob = H
+ user.mind.AddSpell(S)
+
+ if(17)
+ //Tator Kit
+ T.visible_message("A suspicious box appears!")
+ new /obj/item/storage/box/syndicate(drop_location())
+ do_smoke(0, drop_location())
+ if(18)
+ //Captain ID
+ T.visible_message("A golden identification card appears!")
+ new /obj/item/card/id/captains_spare(drop_location())
+ do_smoke(0, drop_location())
+ if(19)
+ //Instrinct Resistance
+ T.visible_message("[user] looks very robust!")
+ var/datum/species/S = user.dna.species
+ S.brute_mod *= 0.5
+ S.burn_mod *= 0.5
+
+ if(20)
+ //Free wizard!
+ T.visible_message("Magic flows out of [src] and into [user]!")
+ user.mind.make_Wizard()
+
+// Butler outfit
+/datum/outfit/butler
+ name = "Butler"
+ uniform = /obj/item/clothing/under/suit_jacket/really_black
+ shoes = /obj/item/clothing/shoes/laceup
+ head = /obj/item/clothing/head/bowlerhat
+ glasses = /obj/item/clothing/glasses/monocle
+ gloves = /obj/item/clothing/gloves/color/white
+
+/obj/effect/proc_holder/spell/targeted/summonmob
+ name = "Summon Servant"
+ desc = "This spell can be used to call your servant, whenever you need it."
+ charge_max = 100
+ clothes_req = 0
+ invocation = "JE VES"
+ invocation_type = "whisper"
+ range = -1
+ level_max = 0 //cannot be improved
+ cooldown_min = 100
+ include_user = 1
+
+ var/mob/living/target_mob
+
+ action_icon_state = "summons"
+
+/obj/effect/proc_holder/spell/targeted/summonmob/cast(list/targets, mob/user = usr)
+ if(!target_mob)
+ return
+ var/turf/Start = get_turf(user)
+ for(var/direction in alldirs)
+ var/turf/T = get_step(Start,direction)
+ if(!T.density)
+ target_mob.Move(T)
diff --git a/code/modules/awaymissions/trigger.dm b/code/modules/awaymissions/trigger.dm
deleted file mode 100644
index 60a43702cb1..00000000000
--- a/code/modules/awaymissions/trigger.dm
+++ /dev/null
@@ -1,40 +0,0 @@
-/obj/effect/step_trigger/message
- var/message //the message to give to the mob
- var/once = 1
-
-/obj/effect/step_trigger/message/Trigger(mob/M as mob)
- if(M.client)
- to_chat(M, "[message]")
- if(once)
- qdel(src)
-
-/obj/effect/step_trigger/teleport_fancy
- var/locationx
- var/locationy
- var/uses = 1 //0 for infinite uses
- var/entersparks = 0
- var/exitsparks = 0
- var/entersmoke = 0
- var/exitsmoke = 0
-
-/obj/effect/step_trigger/teleport_fancy/Trigger(mob/M as mob)
- var/dest = locate(locationx, locationy, z)
- M.Move(dest)
-
- if(entersparks)
- do_sparks(4, 1, src)
- if(exitsparks)
- do_sparks(4, 1, dest)
-
- if(entersmoke)
- var/datum/effect_system/smoke_spread/s = new
- s.set_up(4, 1, src, 0)
- s.start()
- if(exitsmoke)
- var/datum/effect_system/smoke_spread/s = new
- s.set_up(4, 1, dest, 0)
- s.start()
-
- uses--
- if(uses == 0)
- qdel(src)
\ No newline at end of file
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index d8286bc8698..d28a04a11be 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -12,8 +12,12 @@
/obj/structure/closet/crate/necropolis/tendril
desc = "It's watching you suspiciously."
-/obj/structure/closet/crate/necropolis/tendril/New()
+/obj/structure/closet/crate/necropolis/tendril/New(add_loot = TRUE)
..()
+
+ if(!add_loot)
+ return
+
var/loot = rand(1,24)
switch(loot)
if(1)
@@ -68,4 +72,19 @@
new /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor(src)
new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor(src)
if(24)
- new /obj/item/spellbook/oneuse/summonitem(src)
\ No newline at end of file
+ new /obj/item/spellbook/oneuse/summonitem(src)
+
+/obj/structure/closet/crate/necropolis/puzzle
+ name = "puzzling chest"
+
+/obj/structure/closet/crate/necropolis/puzzle/New()
+ ..(FALSE)
+
+ var/loot = rand(1,3)
+ switch(loot)
+ if(1)
+ new /obj/item/soulstone/anybody(src)
+ if(2)
+ new /obj/item/wisp_lantern(src)
+ if(3)
+ new /obj/item/prisoncube(src)
diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm
index d1982ac359d..0aa148eb031 100644
--- a/code/modules/mob/living/simple_animal/hostile/alien.dm
+++ b/code/modules/mob/living/simple_animal/hostile/alien.dm
@@ -4,7 +4,7 @@
icon = 'icons/mob/alien.dmi'
icon_state = "alienh_running"
icon_living = "alienh_running"
- icon_dead = "alien_l"
+ icon_dead = "alienh_dead"
icon_gib = "syndicate_gib"
response_help = "pokes the"
response_disarm = "shoves the"
@@ -40,7 +40,7 @@
name = "alien drone"
icon_state = "aliend_running"
icon_living = "aliend_running"
- icon_dead = "aliend_l"
+ icon_dead = "aliend_dead"
health = 60
maxHealth = 60
melee_damage_lower = 15
@@ -61,7 +61,7 @@
name = "alien sentinel"
icon_state = "aliens_running"
icon_living = "aliens_running"
- icon_dead = "aliens_l"
+ icon_dead = "aliens_dead"
health = 120
maxHealth = 120
melee_damage_lower = 15
@@ -77,7 +77,7 @@
name = "alien queen"
icon_state = "alienq_running"
icon_living = "alienq_running"
- icon_dead = "alienq_l"
+ icon_dead = "alienq_d"
health = 250
maxHealth = 250
melee_damage_lower = 15
diff --git a/code/modules/mob/living/simple_animal/hostile/creature.dm b/code/modules/mob/living/simple_animal/hostile/creature.dm
index 13c695387bd..5b97579b146 100644
--- a/code/modules/mob/living/simple_animal/hostile/creature.dm
+++ b/code/modules/mob/living/simple_animal/hostile/creature.dm
@@ -1,7 +1,6 @@
/mob/living/simple_animal/hostile/creature
name = "creature"
desc = "A sanity-destroying otherthing."
- icon = 'icons/mob/critter.dmi'
speak_emote = list("gibbers")
icon_state = "otherthing"
icon_living = "otherthing"
diff --git a/code/modules/mob/living/simple_animal/hostile/mining/necropolis_tendril.dm b/code/modules/mob/living/simple_animal/hostile/mining/necropolis_tendril.dm
index 2ee9c387140..c6bc205627e 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining/necropolis_tendril.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining/necropolis_tendril.dm
@@ -12,7 +12,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
@@ -73,7 +73,7 @@
qdel(src)
/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
\ No newline at end of file
+ mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
new file mode 100644
index 00000000000..57e851460c8
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
@@ -0,0 +1,111 @@
+/mob/living/simple_animal/hostile/netherworld
+ name = "creature"
+ desc = "A sanity-destroying otherthing from the netherworld."
+ icon_state = "otherthing"
+ icon_living = "otherthing"
+ icon_dead = "otherthing-dead"
+ health = 80
+ maxHealth = 80
+ obj_damage = 100
+ melee_damage_lower = 25
+ melee_damage_upper = 50
+ attacktext = "slashes"
+ attack_sound = 'sound/weapons/bladeslice.ogg'
+ faction = list("creature")
+ speak_emote = list("screams")
+ gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE
+ 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)
+ minbodytemp = 0
+ faction = list("nether")
+
+/mob/living/simple_animal/hostile/netherworld/migo
+ name = "mi-go"
+ desc = "A pinkish, fungoid crustacean-like creature with numerous pairs of clawed appendages and a head covered with waving antennae."
+ speak_emote = list("screams", "clicks", "chitters", "barks", "moans", "growls", "meows", "reverberates", "roars", "squeaks", "rattles", "exclaims", "yells", "remarks", "mumbles", "jabbers", "stutters", "seethes")
+ icon_state = "mi-go"
+ icon_living = "mi-go"
+ icon_dead = "mi-go-dead"
+ attacktext = "lacerates"
+ speed = -0.5
+ var/static/list/migo_sounds
+ deathmessage = "wails as its form turns into a pulpy mush."
+ death_sound = 'sound/voice/hiss6.ogg'
+
+/mob/living/simple_animal/hostile/netherworld/migo/Initialize()
+ . = ..()
+ migo_sounds = list('sound/items/bubblewrap.ogg', 'sound/items/change_jaws.ogg', 'sound/items/crowbar.ogg', 'sound/items/drink.ogg', 'sound/items/deconstruct.ogg', 'sound/items/change_drill.ogg', 'sound/items/dodgeball.ogg', 'sound/items/eatfood.ogg', 'sound/items/screwdriver.ogg', 'sound/items/weeoo1.ogg', 'sound/items/wirecutter.ogg', 'sound/items/welder.ogg', 'sound/items/zip.ogg', 'sound/items/rped.ogg', 'sound/items/ratchet.ogg', 'sound/items/polaroid1.ogg', 'sound/items/pshoom.ogg', 'sound/items/airhorn.ogg', 'sound/voice/bcreep.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/ed209_20sec.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss6.ogg', 'sound/voice/mpatchedup.ogg', 'sound/voice/mfeelbetter.ogg', 'sound/weapons/sear.ogg', 'sound/ambience/antag/tatoralert.ogg', 'sound/mecha/nominal.ogg', 'sound/mecha/weapdestr.ogg', 'sound/mecha/critdestr.ogg', 'sound/mecha/imag_enh.ogg', 'sound/effects/adminhelp.ogg', 'sound/effects/alert.ogg', 'sound/effects/attackblob.ogg', 'sound/effects/bamf.ogg', 'sound/effects/blobattack.ogg', 'sound/effects/break_stone.ogg', 'sound/effects/bubbles.ogg', 'sound/effects/bubbles2.ogg', 'sound/effects/clang.ogg', 'sound/effects/clownstep2.ogg', 'sound/effects/dimensional_rend.ogg', 'sound/effects/doorcreaky.ogg', 'sound/effects/empulse.ogg', 'sound/effects/explosionfar.ogg', 'sound/effects/explosion1.ogg', 'sound/effects/grillehit.ogg', 'sound/effects/genetics.ogg', 'sound/effects/heartbeat.ogg', 'sound/effects/hyperspace_begin.ogg', 'sound/effects/hyperspace_end.ogg', 'sound/goonstation/effects/screech.ogg', 'sound/effects/phasein.ogg', 'sound/effects/picaxe1.ogg', 'sound/effects/sparks1.ogg', 'sound/effects/smoke.ogg', 'sound/effects/splat.ogg', 'sound/effects/snap.ogg', 'sound/effects/tendril_destroyed.ogg', 'sound/effects/supermatter.ogg', 'sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg', 'sound/misc/bloblarm.ogg', 'sound/goonstation/misc/airraid_loop.ogg', 'sound/misc/interference.ogg', 'sound/misc/notice1.ogg', 'sound/misc/notice2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/misc/slip.ogg', 'sound/weapons/armbomb.ogg', 'sound/weapons/chainsaw.ogg', 'sound/weapons/emitter.ogg', 'sound/weapons/emitter2.ogg', 'sound/weapons/blade1.ogg', 'sound/weapons/bladeslice.ogg', 'sound/weapons/blastcannon.ogg', 'sound/weapons/blaster.ogg', 'sound/weapons/bulletflyby3.ogg', 'sound/weapons/circsawhit.ogg', 'sound/weapons/cqchit2.ogg', 'sound/weapons/drill.ogg', 'sound/weapons/genhit1.ogg', 'sound/weapons/gunshots/gunshot_silenced.ogg', 'sound/weapons/gunshots/gunshot.ogg', 'sound/weapons/handcuffs.ogg', 'sound/weapons/homerun.ogg', 'sound/weapons/kenetic_accel.ogg', 'sound/machines/fryer/deep_fryer_emerge.ogg', 'sound/machines/airlock_alien_prying.ogg', 'sound/machines/airlock_close.ogg', 'sound/machines/airlockforced.ogg', 'sound/machines/airlock_open.ogg', 'sound/machines/alarm.ogg', 'sound/machines/blender.ogg', 'sound/machines/boltsdown.ogg', 'sound/machines/boltsup.ogg', 'sound/machines/buzz-sigh.ogg', 'sound/machines/buzz-two.ogg', 'sound/machines/chime.ogg', 'sound/machines/defib_charge.ogg', 'sound/machines/defib_failed.ogg', 'sound/machines/defib_ready.ogg', 'sound/machines/defib_zap.ogg', 'sound/machines/deniedbeep.ogg', 'sound/machines/ding.ogg', 'sound/machines/disposalflush.ogg', 'sound/machines/door_close.ogg', 'sound/machines/door_open.ogg', 'sound/machines/engine_alert1.ogg', 'sound/machines/engine_alert2.ogg', 'sound/machines/hiss.ogg', 'sound/machines/honkbot_evil_laugh.ogg', 'sound/machines/juicer.ogg', 'sound/machines/ping.ogg', 'sound/ambience/signal.ogg', 'sound/machines/synth_no.ogg', 'sound/machines/synth_yes.ogg', 'sound/machines/terminal_alert.ogg', 'sound/machines/twobeep.ogg', 'sound/machines/ventcrawl.ogg', 'sound/machines/warning-buzzer.ogg', 'sound/ai/outbreak5.ogg', 'sound/ai/outbreak7.ogg', 'sound/ai/poweroff.ogg', 'sound/ai/radiation.ogg', 'sound/ai/shuttlecalled.ogg', 'sound/ai/shuttledock.ogg', 'sound/ai/shuttlerecalled.ogg', 'sound/ai/aimalf.ogg') //hahahaha fuck you code divers
+
+/mob/living/simple_animal/hostile/netherworld/migo/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
+ ..()
+ if(stat)
+ return
+ var/chosen_sound = pick(migo_sounds)
+ playsound(src, chosen_sound, 50, TRUE)
+
+/mob/living/simple_animal/hostile/netherworld/migo/Life()
+ ..()
+ if(stat)
+ return
+ if(prob(10))
+ var/chosen_sound = pick(migo_sounds)
+ playsound(src, chosen_sound, 50, TRUE)
+
+/mob/living/simple_animal/hostile/netherworld/blankbody
+ name = "blank body"
+ desc = "This looks human enough, but its flesh has an ashy texture, and it's face is featureless save an eerie smile."
+ icon_state = "blank-body"
+ icon_living = "blank-body"
+ icon_dead = "blank-dead"
+ gold_core_spawnable = CHEM_MOB_SPAWN_INVALID
+ health = 100
+ maxHealth = 100
+ melee_damage_lower = 5
+ melee_damage_upper = 10
+ attacktext = "punches"
+ deathmessage = "falls apart into a fine dust."
+
+/mob/living/simple_animal/hostile/spawner
+ name = "netherworld link"
+ desc = null //see examine()
+ icon_state = "nether"
+ health = 50
+ spawn_time = 600 //1 minute
+ max_mobs = 15
+ icon = 'icons/mob/nest.dmi'
+ spawn_text = "crawls through"
+ mob_types = list(/mob/living/simple_animal/hostile/netherworld/migo, /mob/living/simple_animal/hostile/netherworld, /mob/living/simple_animal/hostile/netherworld/blankbody)
+ faction = list("nether")
+
+/obj/structure/spawner/nether/Initialize()
+ .=..()
+ START_PROCESSING(SSprocessing, src)
+
+/obj/structure/spawner/nether/examine(mob/user)
+ ..()
+ if(isskeleton(user))
+ to_chat(user, "A direct link to another dimension full of creatures very happy to see you. You can see your house from here!")
+ else
+ to_chat(user, "A direct link to another dimension full of creatures not very happy to see you. Entering the link would be a very bad idea.")
+
+/obj/structure/spawner/nether/attack_hand(mob/user)
+ . = ..()
+ if(isskeleton(user))
+ to_chat(user, "You don't feel like going home yet...")
+ else
+ user.visible_message("[user] is violently pulled into the link!", \
+ "Touching the portal, you are quickly pulled through into a world of unimaginable horror!")
+ contents.Add(user)
+
+/obj/structure/spawner/nether/process()
+ for(var/mob/living/M in contents)
+ if(M)
+ playsound(src, 'sound/magic/demon_consume.ogg', 50, 1)
+ M.adjustBruteLoss(60)
+ new /obj/effect/gibspawner/generic(get_turf(M), M)
+ if(M.stat == DEAD)
+ var/mob/living/simple_animal/hostile/netherworld/blankbody/blank
+ blank = new(loc)
+ blank.name = "[M]"
+ blank.desc = "It's [M], but [M.p_their()] flesh has an ashy texture, and [M.p_their()] face is featureless save an eerie smile."
+ visible_message("[M] reemerges from the link!")
+ qdel(M)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/spawner.dm b/code/modules/mob/living/simple_animal/spawner.dm
index 38a9c176be7..747c7690150 100644
--- a/code/modules/mob/living/simple_animal/spawner.dm
+++ b/code/modules/mob/living/simple_animal/spawner.dm
@@ -7,7 +7,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
move_resist = MOVE_FORCE_VERY_STRONG
@@ -39,7 +39,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_type = pick(mob_types)
+ var/mob/living/simple_animal/L = new chosen_type(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
@@ -51,7 +52,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("syndicate")
/mob/living/simple_animal/hostile/spawner/mining
@@ -64,21 +65,21 @@
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)
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/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)
diff --git a/code/modules/nano/nanoexternal.dm b/code/modules/nano/nanoexternal.dm
index 6864c834f3a..8e7269972fd 100644
--- a/code/modules/nano/nanoexternal.dm
+++ b/code/modules/nano/nanoexternal.dm
@@ -40,6 +40,14 @@
/datum/proc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/nano_ui/master_ui = null, var/datum/topic_state/state = default_state)
return
+/**
+ * The UI-close proc is called when the UI is closed.
+ *
+ * @param user /mob The mob who was interacting with this UI.
+ */
+/datum/proc/on_ui_close(mob/user)
+ return
+
/**
* The ui_data proc is used to get data for the interface
*
diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm
index 1dbdcc05b92..5bd0f3827ac 100644
--- a/code/modules/nano/nanoui.dm
+++ b/code/modules/nano/nanoui.dm
@@ -444,6 +444,8 @@ nanoui is used to open and update nano browser uis
for(var/datum/nanoui/child in children)
child.close()
+ src_object.on_ui_close(user)
+
/**
* Set the UI window to call the nanoclose verb when the window is closed
* This allows Nano to handle closed windows
diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm
index 647c690a40d..3cba868a379 100644
--- a/code/modules/projectiles/guns/projectile/revolver.dm
+++ b/code/modules/projectiles/guns/projectile/revolver.dm
@@ -299,6 +299,18 @@
user.apply_damage(300, BRUTE, affecting)
user.visible_message("[user.name] fires [src] at [user.p_their()] head!", "You fire [src] at your head!", "You hear a gunshot!")
+/obj/item/gun/projectile/revolver/russian/soul
+ name = "cursed Russian revolver"
+ desc = "To play with this revolver requires wagering your very soul."
+
+/obj/item/gun/projectile/revolver/russian/soul/shoot_self(mob/living/user)
+ ..()
+ var/obj/item/soulstone/anybody/SS = new /obj/item/soulstone/anybody(get_turf(src))
+ if(!SS.transfer_soul("FORCE", user)) //Something went wrong
+ qdel(SS)
+ return
+ user.visible_message("[user.name]'s soul is captured by \the [src]!", "You've lost the gamble! Your soul is forfeit!")
+
/obj/item/gun/projectile/revolver/capgun
name = "cap gun"
desc = "Looks almost like the real thing! Ages 8 and up."
diff --git a/code/modules/reagents/chemistry/reagents/alcohol.dm b/code/modules/reagents/chemistry/reagents/alcohol.dm
index 6c22360face..6dde9d2a4ec 100644
--- a/code/modules/reagents/chemistry/reagents/alcohol.dm
+++ b/code/modules/reagents/chemistry/reagents/alcohol.dm
@@ -115,6 +115,24 @@
update_flags |= M.adjustToxLoss(1, FALSE)
return list(0, update_flags)
+/datum/reagent/consumable/ethanol/hooch
+ name = "Hooch"
+ id = "hooch"
+ description = "Either someone's failure at cocktail making or attempt in alcohol production. In any case, do you really want to drink that?"
+ color = "#664300" // rgb: 102, 67, 0
+ dizzy_adj = 7
+ alcohol_perc = 1
+ drink_icon = "glass_brown2"
+ drink_name = "Hooch"
+ drink_desc = "You've really hit rock bottom now... your liver packed its bags and left last night."
+ taste_message = "pure resignation"
+
+/datum/reagent/consumable/ethanol/hooch/on_mob_life(mob/living/carbon/M)
+ if(M.mind && M.mind.assigned_role == "Assistant")
+ M.heal_organ_damage(1, 1)
+ . = 1
+ return ..() || .
+
/datum/reagent/consumable/ethanol/rum
name = "Rum"
id = "rum"
@@ -1361,3 +1379,15 @@
taste_message = flavor
if(holder.my_atom)
holder.my_atom.on_reagent_change()
+
+/datum/reagent/consumable/ethanol/bacchus_blessing //An EXTREMELY powerful drink. Smashed in seconds, dead in minutes.
+ name = "Bacchus' Blessing"
+ id = "bacchus_blessing"
+ description = "Unidentifiable mixture. Unmeasurably high alcohol content."
+ color = rgb(51, 19, 3) //Sickly brown
+ dizzy_adj = 21
+ alcohol_perc = 3 //I warned you
+ drink_icon = "glass_brown2"
+ drink_name = "Bacchus' Blessing"
+ drink_desc = "You didn't think it was possible for a liquid to be so utterly revolting. Are you sure about this...?"
+ taste_message = "a wall of bricks"
diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm
index 345ac4a9c6f..77118450aaa 100644
--- a/code/modules/reagents/chemistry/reagents/medicine.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine.dm
@@ -290,6 +290,11 @@
addiction_chance = 5
taste_message = "health"
+/datum/reagent/medicine/omnizine/godblood
+ name = "Godblood"
+ description = "Slowly heals all damage types. Has a rather high overdose threshold. Glows with mysterious power."
+ overdose_threshold = 150
+
/datum/reagent/medicine/omnizine/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
update_flags |= M.adjustToxLoss(-1*REAGENTS_EFFECT_MULTIPLIER, FALSE)
diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm
index 4cf50c9f661..8048c21a283 100644
--- a/code/modules/reagents/chemistry/reagents/toxins.dm
+++ b/code/modules/reagents/chemistry/reagents/toxins.dm
@@ -1174,3 +1174,14 @@
M.electrocute_act(rand(5, 20), "Teslium in their body", 1, TRUE) //Override because it's caused from INSIDE of you
playsound(M, "sparks", 50, 1)
return ..()
+
+/datum/reagent/gluttonytoxin
+ name = "Gluttony's Blessing"
+ id = "gluttonytoxin"
+ description = "An advanced corruptive toxin produced by something terrible."
+ reagent_state = LIQUID
+ color = "#5EFF3B" //RGB: 94, 255, 59
+ taste_message = "decay"
+
+/datum/reagent/gluttonytoxin/reaction_mob(mob/living/L, method=TOUCH, reac_volume)
+ L.ForceContractDisease(new /datum/disease/transformation/morph())
diff --git a/code/modules/reagents/chemistry/recipes/drinks.dm b/code/modules/reagents/chemistry/recipes/drinks.dm
index 2f3eda996b0..5d088bd9ccb 100644
--- a/code/modules/reagents/chemistry/recipes/drinks.dm
+++ b/code/modules/reagents/chemistry/recipes/drinks.dm
@@ -851,4 +851,20 @@
required_reagents = list("rum" = 5, "cream" = 5, "egg" = 5)
result_amount = 15
mix_message = "The eggs nog together. Pretend that \"nog\" is a verb."
- mix_sound = 'sound/goonstation/misc/drinkfizz.ogg'
\ No newline at end of file
+ mix_sound = 'sound/goonstation/misc/drinkfizz.ogg'
+
+/datum/chemical_reaction/hooch
+ name = "Hooch"
+ id = "hooch"
+ result = "hooch"
+ required_reagents = list("ethanol" = 2, "fuel" = 1)
+ result_amount = 3
+ required_catalysts = list("enzyme" = 1)
+
+/datum/chemical_reaction/bacchus_blessing
+ name = "Bacchus' Blessing"
+ id = "bacchus_blessing"
+ result = "bacchus_blessing"
+ required_reagents = list("hooch" = 1, "absinthe" = 1, "manlydorf" = 1, "syndicatebomb" = 1)
+ result_amount = 4
+ mix_message = "The mixture turns to a sickening froth."
\ No newline at end of file
diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm
index e28ec4c0cff..0d3d4f17252 100644
--- a/code/modules/reagents/reagent_containers/syringes.dm
+++ b/code/modules/reagents/reagent_containers/syringes.dm
@@ -289,12 +289,6 @@
icon_state = "[rounded_vol]"
item_state = "syringe_[rounded_vol]"
-
-////////////////////////////////////////////////////////////////////////////////
-/// Syringes. END
-////////////////////////////////////////////////////////////////////////////////
-
-
/obj/item/reagent_containers/syringe/antiviral
name = "Syringe (spaceacillin)"
desc = "Contains antiviral agents."
@@ -327,3 +321,10 @@
name = "bioterror syringe"
desc = "Contains several paralyzing reagents."
list_reagents = list("neurotoxin" = 5, "capulettium_plus" = 5, "sodium_thiopental" = 5)
+
+/obj/item/reagent_containers/syringe/gluttony
+ name = "Gluttony's Blessing"
+ desc = "A syringe recovered from a dread place. It probably isn't wise to use."
+ amount_per_transfer_from_this = 1
+ volume = 1
+ list_reagents = list("gluttonytoxin" = 1)
\ No newline at end of file
diff --git a/code/modules/ruins/lavalandruin_code/dead_ratvar.dm b/code/modules/ruins/lavalandruin_code/dead_ratvar.dm
new file mode 100644
index 00000000000..915597a162d
--- /dev/null
+++ b/code/modules/ruins/lavalandruin_code/dead_ratvar.dm
@@ -0,0 +1,244 @@
+// Dead Ratvar
+/obj/structure/dead_ratvar
+ name = "hulking wreck"
+ desc = "The remains of a monstrous war machine."
+ icon = 'icons/obj/lavaland/dead_ratvar.dmi'
+ icon_state = "dead_ratvar"
+ flags = ON_BORDER
+ appearance_flags = 0
+ layer = FLY_LAYER
+ anchored = TRUE
+ density = TRUE
+ bound_width = 416
+ bound_height = 64
+ pixel_y = -10
+ unacidable = TRUE
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF
+
+// An "overlay" used by clockwork walls and floors to appear normal to mesons.
+/obj/effect/clockwork/overlay
+ mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ var/atom/linked
+
+/obj/effect/clockwork/overlay/examine(mob/user)
+ if(linked)
+ linked.examine(user)
+
+/obj/effect/clockwork/overlay/ex_act()
+ return FALSE
+
+/obj/effect/clockwork/overlay/singularity_act()
+ return
+/obj/effect/clockwork/overlay/singularity_pull()
+ return
+
+/obj/effect/clockwork/overlay/singularity_pull(S, current_size)
+ return
+
+/obj/effect/clockwork/overlay/Destroy()
+ if(linked)
+ linked = null
+ . = ..()
+
+/obj/effect/clockwork/overlay/wall
+ name = "clockwork wall"
+ icon = 'icons/turf/walls/clockwork_wall.dmi'
+ icon_state = "clockwork_wall"
+ canSmoothWith = list(/obj/effect/clockwork/overlay/wall, /obj/structure/falsewall/brass)
+ smooth = SMOOTH_TRUE
+ layer = CLOSED_TURF_LAYER
+
+/obj/effect/clockwork/overlay/wall/Initialize(mapload)
+ . = ..()
+ queue_smooth_neighbors(src)
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/queue_smooth, src), 1)
+
+/obj/effect/clockwork/overlay/wall/Destroy()
+ queue_smooth_neighbors(src)
+ return ..()
+
+/obj/effect/clockwork/overlay/floor
+ icon = 'icons/turf/floors.dmi'
+ icon_state = "clockwork_floor"
+ layer = TURF_LAYER
+ plane = FLOOR_PLANE
+
+/obj/effect/clockwork/overlay/floor/bloodcult //this is used by BLOOD CULT, it shouldn't use such a path...
+ icon_state = "cult"
+
+// Wall gears
+//A massive gear, effectively a girder for clocks.
+/obj/structure/clockwork/wall_gear
+ name = "massive gear"
+ icon = 'icons/obj/clockwork_objects.dmi'
+ icon_state = "wall_gear"
+ climbable = TRUE
+ max_integrity = 100
+ can_deconstruct = TRUE
+ desc = "A massive brass gear. You could probably secure or unsecure it with a wrench, or just climb over it."
+
+/obj/structure/clockwork/wall_gear/displaced
+ anchored = FALSE
+
+/obj/structure/clockwork/wall_gear/Initialize()
+ . = ..()
+ new /obj/effect/temp_visual/ratvar/gear(get_turf(src))
+
+/obj/structure/clockwork/wall_gear/emp_act(severity)
+ return
+
+/obj/structure/clockwork/wall_gear/attackby(obj/item/I, mob/user, params)
+ if(iswrench(I))
+ default_unfasten_wrench(user, I, 10)
+ return 1
+ else if(isscrewdriver(I))
+ if(anchored)
+ to_chat(user, "[src] needs to be unsecured to disassemble it!")
+ else
+ var/obj/item/screwdriver/S = I
+ user.visible_message("[user] starts to disassemble [src].", "You start to disassemble [src]...")
+ if(do_after(user, 30 * S.toolspeed, target = src) && !anchored)
+ playsound(loc, S.usesound, 50, 1)
+ to_chat(user, "You disassemble [src].")
+ deconstruct(TRUE)
+ return 1
+ else if(istype(I, /obj/item/stack/tile/brass))
+ var/obj/item/stack/tile/brass/W = I
+ if(W.get_amount() < 1)
+ to_chat(user, "You need one brass sheet to do this!")
+ return
+ var/turf/T = get_turf(src)
+ if(iswallturf(T))
+ to_chat(user, "There is already a wall present!")
+ return
+ if(!isfloorturf(T))
+ to_chat(user, "A floor must be present to build a [anchored ? "false ":""]wall!")
+ return
+ if(locate(/obj/structure/falsewall) in T.contents)
+ to_chat(user, "There is already a false wall present!")
+ return
+ to_chat(user, "You start adding [W] to [src]...")
+ if(do_after(user, 20, target = src))
+ var/brass_floor = FALSE
+ if(istype(T, /turf/simulated/floor/clockwork)) //if the floor is already brass, costs less to make(conservation of masssssss)
+ brass_floor = TRUE
+ if(W.use(2 - brass_floor))
+ if(anchored)
+ T.ChangeTurf(/turf/simulated/wall/clockwork)
+ else
+ T.ChangeTurf(/turf/simulated/floor/clockwork)
+ new /obj/structure/falsewall/brass(T)
+ qdel(src)
+ else
+ to_chat(user, "You need more brass to make a [anchored ? "false ":""]wall!")
+ return 1
+ return ..()
+
+/obj/structure/clockwork/wall_gear/deconstruct(disassembled = TRUE)
+ if(can_deconstruct && disassembled)
+ new /obj/item/stack/tile/brass(loc, 3)
+ return ..()
+
+//Shards of Alloy, suitable only as a source of power for a replica fabricator.
+/obj/item/clockwork/alloy_shards
+ name = "replicant alloy shards"
+ desc = "Broken shards of some oddly malleable metal. They occasionally move and seem to glow."
+ icon = 'icons/obj/clockwork_objects.dmi'
+ icon_state = "alloy_shards"
+ resistance_flags = LAVA_PROOF | FIRE_PROOF
+ unacidable = TRUE
+ var/randomsinglesprite = FALSE
+ var/randomspritemax = 2
+ var/sprite_shift = 9
+
+/obj/item/clockwork/alloy_shards/Initialize()
+ . = ..()
+ if(randomsinglesprite)
+ replace_name_desc()
+ icon_state = "[icon_state][rand(1, randomspritemax)]"
+ pixel_x = rand(-sprite_shift, sprite_shift)
+ pixel_y = rand(-sprite_shift, sprite_shift)
+
+/obj/item/clockwork/alloy_shards/proc/replace_name_desc()
+ name = "replicant alloy shard"
+ desc = "A broken shard of some oddly malleable metal. It occasionally moves and seems to glow."
+
+/obj/item/clockwork/alloy_shards/clockgolem_remains
+ name = "clockwork golem scrap"
+ desc = "A pile of scrap metal. It seems damaged beyond repair."
+ icon_state = "clockgolem_dead"
+ sprite_shift = 0
+
+/obj/item/clockwork/alloy_shards/large
+ w_class = WEIGHT_CLASS_TINY
+ randomsinglesprite = TRUE
+ icon_state = "shard_large"
+ sprite_shift = 9
+
+/obj/item/clockwork/alloy_shards/medium
+ w_class = WEIGHT_CLASS_TINY
+ randomsinglesprite = TRUE
+ icon_state = "shard_medium"
+ sprite_shift = 10
+
+/obj/item/clockwork/alloy_shards/medium/gear_bit
+ randomspritemax = 4
+ icon_state = "gear_bit"
+ sprite_shift = 12
+
+/obj/item/clockwork/alloy_shards/medium/gear_bit/replace_name_desc()
+ name = "gear bit"
+ desc = "A broken chunk of a gear. You want it."
+
+/obj/item/clockwork/alloy_shards/medium/gear_bit/large //gives more power
+
+/obj/item/clockwork/alloy_shards/medium/gear_bit/large/replace_name_desc()
+ ..()
+ name = "complex gear bit"
+
+/obj/item/clockwork/alloy_shards/small
+ w_class = WEIGHT_CLASS_TINY
+ randomsinglesprite = TRUE
+ randomspritemax = 3
+ icon_state = "shard_small"
+ sprite_shift = 12
+
+/obj/item/clockwork/alloy_shards/pinion_lock
+ name = "pinion lock"
+ desc = "A dented and scratched gear. It's very heavy."
+ icon_state = "pinion_lock"
+
+/obj/item/clockwork/component/belligerent_eye
+ name = "belligerent eye"
+ desc = "A brass construct with a rotating red center. It's as though it's looking for something to hurt."
+ icon = 'icons/obj/clockwork_objects.dmi'
+ icon_state = "belligerent_eye"
+
+/obj/item/clockwork/component/belligerent_eye/blind_eye
+ name = "blind eye"
+ desc = "A heavy brass eye, its red iris fallen dark."
+ icon_state = "blind_eye"
+ w_class = WEIGHT_CLASS_NORMAL
+
+/obj/item/clockwork/component/geis_capacitor/fallen_armor
+ name = "fallen armor"
+ desc = "Lifeless chunks of armor. They're designed in a strange way and won't fit on you."
+ icon = 'icons/obj/clockwork_objects.dmi'
+ icon_state = "fallen_armor"
+ w_class = WEIGHT_CLASS_NORMAL
+
+//Ratvarian spear: A relatively fragile spear from the Celestial Derelict. Deals extreme damage to silicons and enemy cultists, but doesn't last long when summoned.
+/obj/item/clockwork/weapon/ratvarian_spear
+ name = "ratvarian spear"
+ desc = "A razor-sharp spear made of brass. It thrums with barely-contained energy."
+ icon = 'icons/obj/clockwork_objects.dmi'
+ icon_state = "ratvarian_spear"
+ item_state = "ratvarian_spear"
+ force = 15 //Extra damage is dealt to targets in attack()
+ throwforce = 25
+ armour_penetration = 10
+ sharp = TRUE
+ attack_verb = list("stabbed", "poked", "slashed")
+ hitsound = 'sound/weapons/bladeslice.ogg'
+ w_class = WEIGHT_CLASS_BULKY
+ var/bonus_burn = 5
diff --git a/code/modules/ruins/lavalandruin_code/fountain_hall.dm b/code/modules/ruins/lavalandruin_code/fountain_hall.dm
new file mode 100644
index 00000000000..917ea4e4bd0
--- /dev/null
+++ b/code/modules/ruins/lavalandruin_code/fountain_hall.dm
@@ -0,0 +1,49 @@
+/obj/structure/sacrificealtar
+ name = "sacrificial altar"
+ desc = "An altar designed to perform blood sacrifice for a deity."
+ icon = 'icons/obj/hand_of_god_structures.dmi'
+ icon_state = "sacrificealtar"
+ anchored = TRUE
+ density = FALSE
+ can_buckle = TRUE
+
+/obj/structure/sacrificealtar/attack_hand(mob/living/user)
+ if(user.incapacitated())
+ return
+ if(!has_buckled_mobs())
+ return
+ var/mob/living/L = buckled_mob
+ if(!L)
+ return
+ to_chat(user, "You attempt to sacrifice [L] by invoking the sacrificial ritual.")
+ L.gib()
+ message_admins("[ADMIN_LOOKUPFLW(user)] has sacrificed [key_name_admin(L)] on the sacrificial altar at [AREACOORD(src)].")
+
+/obj/structure/healingfountain
+ name = "healing fountain"
+ desc = "A fountain containing the waters of life."
+ icon = 'icons/obj/hand_of_god_structures.dmi'
+ icon_state = "fountain"
+ anchored = TRUE
+ density = TRUE
+ var/time_between_uses = 1800
+ var/last_process = 0
+
+/obj/structure/healingfountain/attack_hand(mob/living/user)
+ . = ..()
+ if(.)
+ return
+ if(last_process + time_between_uses > world.time)
+ to_chat(user, "The fountain appears to be empty.")
+ return
+ last_process = world.time
+ to_chat(user, "The water feels warm and soothing as you touch it. The fountain immediately dries up shortly afterwards.")
+ user.reagents.add_reagent(/datum/reagent/medicine/omnizine/godblood, 20)
+ update_icon()
+ addtimer(CALLBACK(src, .proc/update_icon), time_between_uses)
+
+/obj/structure/healingfountain/update_icon()
+ if(last_process + time_between_uses > world.time)
+ icon_state = "fountain"
+ else
+ icon_state = "fountain-red"
\ No newline at end of file
diff --git a/code/modules/ruins/lavalandruin_code/pizzaparty.dm b/code/modules/ruins/lavalandruin_code/pizzaparty.dm
new file mode 100644
index 00000000000..f2e73069c1b
--- /dev/null
+++ b/code/modules/ruins/lavalandruin_code/pizzaparty.dm
@@ -0,0 +1,7 @@
+/obj/effect/spawner/lootdrop/pizzaparty
+ name = "pizza bomb spawner"
+ loot = list(/obj/item/pizzabox/margherita = 3,
+ /obj/item/pizzabox/meat = 3,
+ /obj/item/pizzabox/mushroom = 3,
+ /obj/item/pizza_bomb = 1)
+ lootdoubles = FALSE
\ No newline at end of file
diff --git a/code/modules/ruins/lavalandruin_code/puzzle.dm b/code/modules/ruins/lavalandruin_code/puzzle.dm
new file mode 100644
index 00000000000..44383f11a0a
--- /dev/null
+++ b/code/modules/ruins/lavalandruin_code/puzzle.dm
@@ -0,0 +1,351 @@
+/obj/effect/sliding_puzzle
+ name = "Sliding puzzle generator"
+ icon = 'icons/obj/items.dmi' //mapping
+ icon_state = "syndballoon"
+ invisibility = INVISIBILITY_ABSTRACT
+ anchored = TRUE
+ var/list/elements
+ var/floor_type = /turf/simulated/floor/vault
+ var/finished = FALSE
+ var/reward_type = /obj/item/reagent_containers/food/snacks/cookie
+ var/element_type = /obj/structure/puzzle_element
+ var/auto_setup = TRUE
+ var/empty_tile_id
+
+//Gets the turf where the tile with given id should be
+/obj/effect/sliding_puzzle/proc/get_turf_for_id(id)
+ var/turf/center = get_turf(src)
+ switch(id)
+ if(1)
+ return get_step(center,NORTHWEST)
+ if(2)
+ return get_step(center,NORTH)
+ if(3)
+ return get_step(center,NORTHEAST)
+ if(4)
+ return get_step(center,WEST)
+ if(5)
+ return center
+ if(6)
+ return get_step(center,EAST)
+ if(7)
+ return get_step(center,SOUTHWEST)
+ if(8)
+ return get_step(center,SOUTH)
+ if(9)
+ return get_step(center,SOUTHEAST)
+
+/obj/effect/sliding_puzzle/Initialize(mapload)
+ ..()
+ return INITIALIZE_HINT_LATELOAD
+
+/obj/effect/sliding_puzzle/LateInitialize()
+ if(auto_setup)
+ setup()
+
+/obj/effect/sliding_puzzle/proc/check_setup_location()
+ for(var/id in 1 to 9)
+ var/turf/T = get_turf_for_id(id)
+ if(!T)
+ return FALSE
+ if(istype(T, /turf/simulated/wall/indestructible) || istype(T, /turf/simulated/floor/indestructible))
+ return FALSE
+ return TRUE
+
+
+/obj/effect/sliding_puzzle/proc/validate()
+ if(finished)
+ return
+
+ if(elements.len < 8) //Someone broke it
+ qdel(src)
+
+ //Check if everything is in place
+ for(var/id in 1 to 9)
+ var/target_turf = get_turf_for_id(id)
+ var/obj/structure/puzzle_element/E = locate() in target_turf
+ if(id == empty_tile_id && !E) // This location should be empty.
+ continue
+ if(!E || E.id != id) //wrong tile or no tile at all
+ return
+ //Ding ding
+ finish()
+
+/obj/effect/sliding_puzzle/Destroy()
+ if(LAZYLEN(elements))
+ for(var/obj/structure/puzzle_element/E in elements)
+ E.source = null
+ elements.Cut()
+ return ..()
+
+#define COLLAPSE_DURATION 7
+
+/obj/effect/sliding_puzzle/proc/finish()
+ finished = TRUE
+ for(var/mob/M in range(7,src))
+ shake_camera(M, COLLAPSE_DURATION , 1)
+ for(var/obj/structure/puzzle_element/E in elements)
+ E.collapse()
+
+ dispense_reward()
+
+/obj/effect/sliding_puzzle/proc/dispense_reward()
+ new reward_type(get_turf(src))
+
+/obj/effect/sliding_puzzle/proc/is_solvable()
+ var/list/current_ordering = list()
+ for(var/obj/structure/puzzle_element/E in elements_in_order())
+ current_ordering += E.id
+
+ var/swap_tally = 0
+ for(var/i in 1 to current_ordering.len)
+ var/checked_value = current_ordering[i]
+ for(var/j in i to current_ordering.len)
+ if(current_ordering[j] < checked_value)
+ swap_tally++
+
+ return swap_tally % 2 == 0
+
+//swap two tiles in same row
+/obj/effect/sliding_puzzle/proc/make_solvable()
+ var/first_tile_id = 1
+ var/other_tile_id = 2
+ if(empty_tile_id == 1 || empty_tile_id == 2) //Can't swap with empty one so just grab some in second row
+ first_tile_id = 4
+ other_tile_id = 5
+
+ var/turf/T1 = get_turf_for_id(first_tile_id)
+ var/turf/T2 = get_turf_for_id(other_tile_id)
+
+ var/obj/structure/puzzle_element/E1 = locate() in T1
+ var/obj/structure/puzzle_element/E2 = locate() in T2
+
+ E1.forceMove(T2)
+ E2.forceMove(T1)
+
+/proc/cmp_xy_desc(atom/movable/A, atom/movable/B)
+ if(A.y > B.y)
+ return -1
+ if(A.y < B.y)
+ return 1
+ if(A.x > B.x)
+ return 1
+ if(A.x < B.x)
+ return -1
+ return 0
+
+/obj/effect/sliding_puzzle/proc/elements_in_order()
+ return sortTim(elements,cmp=/proc/cmp_xy_desc)
+
+/obj/effect/sliding_puzzle/proc/get_base_icon()
+ var/icon/I = new('icons/obj/puzzle.dmi')
+ var/list/puzzles = icon_states(I)
+ var/puzzle_state = pick(puzzles)
+ var/icon/P = new('icons/obj/puzzle.dmi',puzzle_state)
+ return P
+
+/obj/effect/sliding_puzzle/proc/setup()
+ //First we slice the 96x96 icon into 32x32 pieces
+ var/list/puzzle_pieces = list() //id -> icon list
+
+ var/width = 3
+ var/height = 3
+ var/list/left_ids = list()
+ var/tile_count = width * height
+
+ //Generate per tile icons
+ for(var/id in 1 to tile_count)
+ var/y = width - round((id - 1) / width)
+ var/x = ((id - 1) % width) + 1
+
+ var/x_start = 1 + (x - 1) * world.icon_size
+ var/x_end = x_start + world.icon_size - 1
+ var/y_start = 1 + ((y - 1) * world.icon_size)
+ var/y_end = y_start + world.icon_size - 1
+
+ var/icon/T = get_base_icon()
+ T.Crop(x_start,y_start,x_end,y_end)
+ puzzle_pieces["[id]"] = T
+ left_ids += id
+
+ //Setup random empty tile
+ empty_tile_id = pick_n_take(left_ids)
+ var/turf/empty_tile_turf = get_turf_for_id(empty_tile_id)
+ empty_tile_turf.ChangeTurf(floor_type, keep_icon = FALSE, ignore_air = FALSE)
+ var/mutable_appearance/MA = new(puzzle_pieces["[empty_tile_id]"])
+ MA.layer = empty_tile_turf.layer + 0.1
+ empty_tile_turf.add_overlay(MA)
+
+ elements = list()
+ var/list/empty_spots = left_ids.Copy()
+ for(var/spot_id in empty_spots)
+ var/turf/T = get_turf_for_id(spot_id)
+ T = T.ChangeTurf(floor_type, keep_icon = FALSE, ignore_air = FALSE)
+ var/obj/structure/puzzle_element/E = new element_type(T)
+ elements += E
+ var/chosen_id = pick_n_take(left_ids)
+ E.puzzle_icon = puzzle_pieces["[chosen_id]"]
+ E.source = src
+ E.id = chosen_id
+ E.set_puzzle_icon()
+
+ if(!is_solvable())
+ make_solvable()
+
+/obj/structure/puzzle_element
+ name = "mysterious pillar"
+ desc = "puzzling..."
+ icon = 'icons/obj/lavaland/artefacts.dmi'
+ icon_state = "puzzle_pillar"
+ anchored = FALSE
+ density = TRUE
+ var/id = 0
+ var/obj/effect/sliding_puzzle/source
+ var/icon/puzzle_icon
+
+/obj/structure/puzzle_element/Move(nloc, dir)
+ if(!isturf(nloc) || moving_diagonally || get_dist(get_step(src,dir),get_turf(source)) > 1)
+ return 0
+ else
+ return ..()
+
+/obj/structure/puzzle_element/proc/set_puzzle_icon()
+ cut_overlays()
+ if(puzzle_icon)
+ //Need to scale it down a bit to fit the static border
+ var/icon/C = new(puzzle_icon)
+ C.Scale(19,19)
+ var/mutable_appearance/puzzle_small = new(C)
+ puzzle_small.layer = layer + 0.1
+ puzzle_small.pixel_x = 7
+ puzzle_small.pixel_y = 7
+ add_overlay(puzzle_small)
+
+/obj/structure/puzzle_element/Destroy()
+ if(source)
+ source.elements -= src
+ source.validate()
+ return ..()
+
+//Set the full image on the turf and delete yourself
+/obj/structure/puzzle_element/proc/collapse()
+ var/turf/T = get_turf(src)
+ var/mutable_appearance/MA = new(puzzle_icon)
+ MA.layer = T.layer + 0.1
+ T.add_overlay(MA)
+ //Some basic shaking animation
+ for(var/i in 1 to COLLAPSE_DURATION)
+ animate(src, pixel_x=rand(-5,5), pixel_y=rand(-2,2), time=1)
+ QDEL_IN(src,COLLAPSE_DURATION)
+
+/obj/structure/puzzle_element/Moved()
+ . = ..()
+ source.validate()
+
+//Admin abuse version so you can pick the icon before it sets up
+/obj/effect/sliding_puzzle/admin
+ auto_setup = FALSE
+ var/icon/puzzle_icon
+ var/puzzle_state
+
+/obj/effect/sliding_puzzle/admin/get_base_icon()
+ var/icon/I = new(puzzle_icon,puzzle_state)
+ return I
+
+//Ruin version
+/obj/effect/sliding_puzzle/lavaland
+ reward_type = /obj/structure/closet/crate/necropolis/puzzle
+
+/obj/effect/sliding_puzzle/lavaland/dispense_reward()
+ if(prob(25))
+ //If it's not roaming somewhere else already.
+ var/mob/living/simple_animal/hostile/megafauna/bubblegum/B = locate() in GLOB.mob_list
+ if(!B)
+ reward_type = /mob/living/simple_animal/hostile/megafauna/bubblegum
+ return ..()
+
+//Prison cube version
+/obj/effect/sliding_puzzle/prison
+ auto_setup = FALSE //This will be done by cube proc
+ var/mob/living/prisoner
+ element_type = /obj/structure/puzzle_element/prison
+
+/obj/effect/sliding_puzzle/prison/get_base_icon()
+ if(!prisoner)
+ CRASH("Prison cube without prisoner")
+ prisoner.setDir(SOUTH)
+ var/icon/I = getFlatIcon(prisoner)
+ I.Scale(96,96)
+ return I
+
+/obj/effect/sliding_puzzle/prison/Destroy()
+ if(prisoner)
+ to_chat(prisoner,"With the cube broken by force, you can feel your body falling apart.")
+ prisoner.death()
+ qdel(prisoner)
+ . = ..()
+
+/obj/effect/sliding_puzzle/prison/dispense_reward()
+ prisoner.forceMove(get_turf(src))
+ prisoner.notransform = FALSE
+ prisoner = null
+
+//Some armor so it's harder to kill someone by mistake.
+/obj/structure/puzzle_element/prison
+ armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 50, "rad" = 50, "fire" = 50, "acid" = 50)
+
+/obj/structure/puzzle_element/prison/relaymove(mob/user)
+ return
+
+/obj/item/prisoncube
+ name = "Prison Cube"
+ desc = "Dusty cube with humanoid imprint on it."
+ icon = 'icons/obj/lavaland/artefacts.dmi'
+ icon_state = "prison_cube"
+
+/obj/item/prisoncube/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
+ if(!proximity_flag || !isliving(target))
+ return
+ var/mob/living/victim = target
+ var/mob/living/carbon/carbon_victim = victim
+ //Handcuffed or unconcious
+ if(istype(carbon_victim) && carbon_victim.handcuffed || victim.stat != CONSCIOUS)
+ if(!puzzle_imprison(target))
+ to_chat(user,"[src] does nothing.")
+ return
+ to_chat(user,"You trap [victim] in the prison cube!")
+ qdel(src)
+ else
+ to_chat(user,"[src] only accepts restrained or unconcious prisoners.")
+
+/proc/puzzle_imprison(mob/living/prisoner)
+ var/turf/T = get_turf(prisoner)
+ var/obj/effect/sliding_puzzle/prison/cube = new(T)
+ if(!cube.check_setup_location())
+ qdel(cube)
+ return FALSE
+
+ //First grab the prisoner and move them temporarily into the generator so they won't get thrown around.
+ prisoner.notransform = TRUE
+ prisoner.forceMove(cube)
+ to_chat(prisoner,"You're trapped by the prison cube! You will remain trapped until someone solves it.")
+
+ //Clear the area from objects (and cube user)
+ var/list/things_to_throw = list()
+ for(var/atom/movable/AM in range(1,T))
+ if(!AM.anchored)
+ things_to_throw += AM
+
+ for(var/atom/movable/AM in things_to_throw)
+ var/throwtarget = get_edge_target_turf(T, get_dir(T, get_step_away(AM, T)))
+ AM.throw_at(throwtarget, 2, 3)
+
+ //Create puzzle itself
+ cube.prisoner = prisoner
+ cube.setup()
+
+ //Move them into random block
+ var/obj/structure/puzzle_element/E = pick(cube.elements)
+ prisoner.forceMove(E)
+ return TRUE
\ No newline at end of file
diff --git a/code/modules/ruins/lavalandruin_code/sin_ruins.dm b/code/modules/ruins/lavalandruin_code/sin_ruins.dm
new file mode 100644
index 00000000000..82fbd410ea1
--- /dev/null
+++ b/code/modules/ruins/lavalandruin_code/sin_ruins.dm
@@ -0,0 +1,156 @@
+//These objects are used in the cardinal sin-themed ruins (i.e. Gluttony, Pride...)
+
+// Greed
+/obj/structure/cursed_slot_machine //Greed's slot machine: Used in the Greed ruin. Deals clone damage on each use, with a successful use giving a d20 of fate.
+ name = "greed's slot machine"
+ desc = "High stakes, high rewards."
+ icon = 'icons/obj/economy.dmi'
+ icon_state = "slots-off"
+ anchored = TRUE
+ density = TRUE
+ var/win_prob = 5
+
+/obj/structure/cursed_slot_machine/attack_hand(mob/user)
+ interact(user)
+
+/obj/structure/cursed_slot_machine/interact(mob/living/carbon/human/user)
+ if(!istype(user))
+ return
+
+ if(in_use)
+ return
+
+ in_use = TRUE
+ user.adjustCloneLoss(20)
+ if(user.stat)
+ to_chat(user, "No... just one more try...")
+ user.gib()
+ else
+ user.visible_message("[user] pulls [src]'s lever with a glint in [user.p_their()] eyes!", "You feel a draining as you pull the lever, but you \
+ know it'll be worth it.")
+ icon_state = "slots-on"
+ playsound(src, 'sound/lavaland/cursed_slot_machine.ogg', 50, 0)
+ addtimer(CALLBACK(src, .proc/determine_victor, user), 50)
+
+/obj/structure/cursed_slot_machine/proc/determine_victor(mob/living/user)
+ icon_state = "slots-off"
+ in_use = FALSE
+ if(prob(win_prob))
+ playsound(src, 'sound/lavaland/cursed_slot_machine_jackpot.ogg', 50, 0)
+ new/obj/structure/cursed_money(get_turf(src))
+ if(user)
+ to_chat(user, "You've hit jackpot. Laughter echoes around you as your reward appears in the machine's place.")
+ qdel(src)
+ else
+ if(user)
+ to_chat(user, "Fucking machine! Must be rigged. Still... one more try couldn't hurt, right?")
+
+/obj/structure/cursed_money
+ name = "bag of money"
+ desc = "RICH! YES! YOU KNEW IT WAS WORTH IT! YOU'RE RICH! RICH! RICH!"
+ icon = 'icons/obj/storage.dmi'
+ icon_state = "moneybag"
+ anchored = FALSE
+ density = TRUE
+
+/obj/structure/cursed_money/Initialize()
+ . = ..()
+ addtimer(CALLBACK(src, .proc/collapse), 600)
+
+/obj/structure/cursed_money/proc/collapse()
+ visible_message("[src] falls in on itself, \
+ canvas rotting away and contents vanishing.")
+ qdel(src)
+
+/obj/structure/cursed_money/attack_hand(mob/living/user)
+ . = ..()
+ if(.)
+ return .
+
+ user.visible_message("[user] opens the bag and \
+ and removes a die. The bag then vanishes.",
+ "You open the bag...!\n\
+ And see a bag full of dice. Confused, \
+ you take one... and the bag vanishes.")
+ var/turf/T = get_turf(user)
+ var/obj/item/dice/d20/fate/one_use/critical_fail = new(T)
+ user.put_in_hands(critical_fail)
+ qdel(src)
+
+// Gluttony
+/obj/effect/gluttony //Gluttony's wall: Used in the Gluttony ruin. Only lets the overweight through.
+ name = "gluttony's wall"
+ desc = "Only those who truly indulge may pass."
+ anchored = TRUE
+ density = TRUE
+ icon_state = "blob"
+ icon = 'icons/mob/blob.dmi'
+ color = rgb(145, 150, 0)
+
+/obj/effect/gluttony/CanPass(atom/movable/mover, turf/target)//So bullets will fly over and stuff.
+ if(ishuman(mover))
+ var/mob/living/carbon/human/H = mover
+ if(H.nutrition >= NUTRITION_LEVEL_FAT || (FAT in H.mutations))
+ H.visible_message("[H] pushes through [src]!", "You've seen and eaten worse than this.")
+ return TRUE
+ else
+ to_chat(H, "You're repulsed by even looking at [src]. Only a pig could force themselves to go through it.")
+ if(istype(mover, /mob/living/simple_animal/hostile/morph))
+ return TRUE
+ else
+ return FALSE
+
+// Pride
+/obj/structure/mirror/magic/pride //Pride's mirror: Used in the Pride ruin.
+ name = "pride's mirror"
+ desc = "Pride cometh before the..."
+ icon_state = "magic_mirror"
+
+/obj/structure/mirror/magic/pride/curse(mob/user)
+ user.visible_message("The ground splits beneath [user] as [user.p_their()] hand leaves the mirror!", \
+ "Perfect. Much better! Now nobody will be able to resist yo-")
+
+ var/turf/T = get_turf(user)
+ var/list/levels = space_manager.z_list.Copy()
+ for(var/level in levels)
+ if(!is_teleport_allowed(level))
+ levels -= level
+
+ T.ChangeTurf(/turf/simulated/floor/chasm)
+ var/turf/simulated/floor/chasm/C = T
+ C.drop_x = T.x
+ C.drop_y = T.y
+ C.drop_z = pick(levels)
+ C.drop(user)
+
+// Envy
+/obj/item/kitchen/knife/envy //Envy's knife: Found in the Envy ruin. Attackers take on the appearance of whoever they strike.
+ name = "envy's knife"
+ desc = "Their success will be yours."
+ icon = 'icons/obj/wizard.dmi'
+ icon_state = "render"
+ item_state = "knife"
+ force = 18
+ throwforce = 10
+ w_class = WEIGHT_CLASS_NORMAL
+ hitsound = 'sound/weapons/bladeslice.ogg'
+
+/obj/item/kitchen/knife/envy/afterattack(atom/movable/AM, mob/living/carbon/human/user, proximity)
+ . = ..()
+ if(!proximity)
+ return
+ if(!istype(user))
+ return
+ if(ishuman(AM))
+ var/mob/living/carbon/human/H = AM
+ if(user.real_name != H.dna.real_name)
+ user.real_name = H.dna.real_name
+ H.dna.transfer_identity(user)
+ user.visible_message("[user]'s appearance shifts into [H]'s!", \
+ "[H.p_they(TRUE)] think[H.p_s()] [H.p_theyre()] sooo much better than you. Not anymore, [H.p_they()] won't.")
+
+// Sloth
+/obj/item/paper/fluff/stations/lavaland/sloth/note
+ name = "note from sloth"
+ icon_state = "paper_words"
+ info = "have not gotten around to finishing my cursed item yet sorry - sloth"
diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi
index 26cc4faf2ee..0167380d885 100644
Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ
diff --git a/icons/mob/critter.dmi b/icons/mob/critter.dmi
index 7bf89c1aab1..ddb2ebe5822 100644
Binary files a/icons/mob/critter.dmi and b/icons/mob/critter.dmi differ
diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi
index 409cf04e862..7f84b29d04e 100644
Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ
diff --git a/icons/mob/nest.dmi b/icons/mob/nest.dmi
index 7dab335929e..d838ef6c5da 100644
Binary files a/icons/mob/nest.dmi and b/icons/mob/nest.dmi differ
diff --git a/icons/obj/chairs.dmi b/icons/obj/chairs.dmi
index 1bfe6c2a25e..cc19efc4900 100644
Binary files a/icons/obj/chairs.dmi and b/icons/obj/chairs.dmi differ
diff --git a/icons/obj/clockwork_objects.dmi b/icons/obj/clockwork_objects.dmi
new file mode 100644
index 00000000000..c147f01fdff
Binary files /dev/null and b/icons/obj/clockwork_objects.dmi differ
diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi
index 1bfe41618c4..a20cf61eb33 100644
Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ
diff --git a/icons/obj/hand_of_god_structures.dmi b/icons/obj/hand_of_god_structures.dmi
new file mode 100644
index 00000000000..4f18b2e68d4
Binary files /dev/null and b/icons/obj/hand_of_god_structures.dmi differ
diff --git a/icons/obj/lavaland/artefacts.dmi b/icons/obj/lavaland/artefacts.dmi
index a0486389b74..cd2c6da08ee 100644
Binary files a/icons/obj/lavaland/artefacts.dmi and b/icons/obj/lavaland/artefacts.dmi differ
diff --git a/icons/obj/lavaland/dead_ratvar.dmi b/icons/obj/lavaland/dead_ratvar.dmi
new file mode 100644
index 00000000000..5e6e9087bd0
Binary files /dev/null and b/icons/obj/lavaland/dead_ratvar.dmi differ
diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi
index f57c6ded447..f28e5f83a33 100644
Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ
diff --git a/icons/obj/puzzle.dmi b/icons/obj/puzzle.dmi
new file mode 100644
index 00000000000..f623142beb4
Binary files /dev/null and b/icons/obj/puzzle.dmi differ
diff --git a/icons/obj/smooth_structures/catwalk_clockwork.dmi b/icons/obj/smooth_structures/catwalk_clockwork.dmi
new file mode 100644
index 00000000000..ecef1df3897
Binary files /dev/null and b/icons/obj/smooth_structures/catwalk_clockwork.dmi differ
diff --git a/icons/obj/smooth_structures/catwalk_clockwork_large.dmi b/icons/obj/smooth_structures/catwalk_clockwork_large.dmi
new file mode 100644
index 00000000000..675ebd91f6d
Binary files /dev/null and b/icons/obj/smooth_structures/catwalk_clockwork_large.dmi differ
diff --git a/icons/obj/smooth_structures/lattice_clockwork.dmi b/icons/obj/smooth_structures/lattice_clockwork.dmi
new file mode 100644
index 00000000000..23beeecb276
Binary files /dev/null and b/icons/obj/smooth_structures/lattice_clockwork.dmi differ
diff --git a/icons/obj/smooth_structures/lattice_clockwork_large.dmi b/icons/obj/smooth_structures/lattice_clockwork_large.dmi
new file mode 100644
index 00000000000..3b035d8736b
Binary files /dev/null and b/icons/obj/smooth_structures/lattice_clockwork_large.dmi differ
diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi
index 411f371af9b..400b42105f4 100644
Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ
diff --git a/icons/turf/walls/clockwork_wall.dmi b/icons/turf/walls/clockwork_wall.dmi
new file mode 100644
index 00000000000..8263e901d00
Binary files /dev/null and b/icons/turf/walls/clockwork_wall.dmi differ
diff --git a/paradise.dme b/paradise.dme
index c49361b8e20..e206811b198 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -1255,7 +1255,6 @@
#include "code\modules\awaymissions\loot.dm"
#include "code\modules\awaymissions\map_rng.dm"
#include "code\modules\awaymissions\pamphlet.dm"
-#include "code\modules\awaymissions\trigger.dm"
#include "code\modules\awaymissions\zlevel.dm"
#include "code\modules\awaymissions\zvis.dm"
#include "code\modules\awaymissions\maploader\dmm_suite.dm"
@@ -1911,6 +1910,7 @@
#include "code\modules\mob\living\simple_animal\hostile\killertomato.dm"
#include "code\modules\mob\living\simple_animal\hostile\mimic.dm"
#include "code\modules\mob\living\simple_animal\hostile\mushroom.dm"
+#include "code\modules\mob\living\simple_animal\hostile\netherworld.dm"
#include "code\modules\mob\living\simple_animal\hostile\pirate.dm"
#include "code\modules\mob\living\simple_animal\hostile\russian.dm"
#include "code\modules\mob\living\simple_animal\hostile\spaceworms.dm"
@@ -2293,8 +2293,13 @@
#include "code\modules\ruins\ruin_areas.dm"
#include "code\modules\ruins\lavalandruin_code\animal_hospital.dm"
#include "code\modules\ruins\lavalandruin_code\ash_walker_den.dm"
+#include "code\modules\ruins\lavalandruin_code\dead_ratvar.dm"
+#include "code\modules\ruins\lavalandruin_code\fountain_hall.dm"
#include "code\modules\ruins\lavalandruin_code\hermit.dm"
+#include "code\modules\ruins\lavalandruin_code\pizzaparty.dm"
+#include "code\modules\ruins\lavalandruin_code\puzzle.dm"
#include "code\modules\ruins\lavalandruin_code\seed_vault.dm"
+#include "code\modules\ruins\lavalandruin_code\sin_ruins.dm"
#include "code\modules\ruins\lavalandruin_code\syndicate_base.dm"
#include "code\modules\ruins\objects_and_mobs\gym.dm"
#include "code\modules\ruins\objects_and_mobs\necropolis_gate.dm"
diff --git a/sound/lavaland/cursed_slot_machine.ogg b/sound/lavaland/cursed_slot_machine.ogg
new file mode 100644
index 00000000000..80911861bab
Binary files /dev/null and b/sound/lavaland/cursed_slot_machine.ogg differ
diff --git a/sound/lavaland/cursed_slot_machine_jackpot.ogg b/sound/lavaland/cursed_slot_machine_jackpot.ogg
new file mode 100644
index 00000000000..19a4c417a96
Binary files /dev/null and b/sound/lavaland/cursed_slot_machine_jackpot.ogg differ
diff --git a/sound/machines/fryer/deep_fryer_emerge.ogg b/sound/machines/fryer/deep_fryer_emerge.ogg
new file mode 100644
index 00000000000..a803dd4c677
Binary files /dev/null and b/sound/machines/fryer/deep_fryer_emerge.ogg differ