diff --git a/_maps/RandomRuins/IceRuins/skyrat/icemoon_underground_syndicate_base1_skyrat.dmm b/_maps/RandomRuins/IceRuins/skyrat/icemoon_underground_syndicate_base1_skyrat.dmm
index 4bb06861e10..0330ddf8031 100644
--- a/_maps/RandomRuins/IceRuins/skyrat/icemoon_underground_syndicate_base1_skyrat.dmm
+++ b/_maps/RandomRuins/IceRuins/skyrat/icemoon_underground_syndicate_base1_skyrat.dmm
@@ -872,7 +872,7 @@
/area/ruin/syndicate_lava_base/cargo)
"gp" = (
/obj/machinery/light/floor,
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/turf/open/floor/iron/dark,
/area/ruin/syndicate_lava_base/medbay)
"gs" = (
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_strong_rock.dmm b/_maps/RandomRuins/LavaRuins/lavaland_strong_rock.dmm
index f236a25a6a0..ad90df10167 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_strong_rock.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_strong_rock.dmm
@@ -4,7 +4,7 @@
/area/template_noop)
"b" = (
/turf/closed/mineral/strong,
-/area/template_noop)
+/area/lavaland/surface/outdoors)
(1,1,1) = {"
a
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
index 4cc31bca411..7497b5bb907 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
@@ -3716,7 +3716,7 @@
"OZ" = (
/obj/effect/turf_decal/bot,
/obj/effect/decal/cleanable/dirt,
-/obj/machinery/suit_storage_unit/syndicate,
+/obj/machinery/suit_storage_unit/syndicate/lavaland,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/ruin/syndicate_lava_base/engineering)
diff --git a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_arena.dmm b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_arena.dmm
index bce0b173159..47fd82ad043 100644
--- a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_arena.dmm
+++ b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_arena.dmm
@@ -113,10 +113,9 @@
/obj/structure/stone_tile{
dir = 4
},
-/mob/living/simple_animal/hostile/asteroid/hivelord{
+/mob/living/basic/mining/hivelord/no_wander{
color = "red";
name = "gate guardian";
- wander = 0
},
/turf/open/lava/smooth/lava_land_surface{
slowdown = 0
@@ -308,10 +307,9 @@
/obj/structure/stone_tile{
dir = 1
},
-/mob/living/simple_animal/hostile/asteroid/hivelord{
+/mob/living/basic/mining/hivelord/no_wander{
color = "red";
name = "gate guardian";
- wander = 0
},
/turf/open/lava/smooth/lava_land_surface{
slowdown = 0
@@ -627,10 +625,9 @@
/obj/structure/stone_tile{
dir = 1
},
-/mob/living/simple_animal/hostile/asteroid/hivelord{
+/mob/living/basic/mining/hivelord/no_wander{
color = "red";
name = "gate guardian";
- wander = 0
},
/turf/open/indestructible/boss,
/area/lavaland/surface/outdoors)
@@ -778,10 +775,9 @@
/obj/structure/stone_tile{
dir = 4
},
-/mob/living/simple_animal/hostile/asteroid/hivelord{
+/mob/living/basic/mining/hivelord/no_wander{
color = "red";
name = "gate guardian";
- wander = 0
},
/turf/open/indestructible/boss,
/area/lavaland/surface/outdoors)
diff --git a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm
index 7b81c9e2193..957a669e53c 100644
--- a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm
+++ b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm
@@ -1393,7 +1393,7 @@
/turf/open/floor/plating,
/area/ruin/syndicate_lava_base/medbay)
"oe" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/turf/open/floor/iron/dark,
/area/ruin/syndicate_lava_base/medbay)
"oi" = (
diff --git a/_maps/RandomRuins/SpaceRuins/atmosasteroidruin.dmm b/_maps/RandomRuins/SpaceRuins/atmosasteroidruin.dmm
index 1d63a1a0070..7e3b7000c42 100644
--- a/_maps/RandomRuins/SpaceRuins/atmosasteroidruin.dmm
+++ b/_maps/RandomRuins/SpaceRuins/atmosasteroidruin.dmm
@@ -637,7 +637,7 @@
/obj/effect/turf_decal/tile/yellow/half{
dir = 4
},
-/mob/living/simple_animal/hostile/asteroid/hivelord,
+/mob/living/basic/mining/hivelord,
/turf/open/floor/iron/co2_pressurized,
/area/ruin/space/has_grav/atmosasteroid)
"RK" = (
diff --git a/_maps/RandomRuins/SpaceRuins/prey_pod.dmm b/_maps/RandomRuins/SpaceRuins/prey_pod.dmm
index 9089dea664c..6f53409b873 100644
--- a/_maps/RandomRuins/SpaceRuins/prey_pod.dmm
+++ b/_maps/RandomRuins/SpaceRuins/prey_pod.dmm
@@ -17,7 +17,7 @@
/obj/structure/chair/comfy/shuttle{
dir = 4
},
-/mob/living/simple_animal/hostile/asteroid/hivelord,
+/mob/living/basic/mining/hivelord,
/turf/open/floor/mineral/titanium/white/airless,
/area/ruin/space/has_grav)
"p" = (
@@ -32,7 +32,7 @@
/area/ruin/space/has_grav)
"D" = (
/obj/structure/chair/comfy/shuttle,
-/mob/living/simple_animal/hostile/asteroid/hivelord,
+/mob/living/basic/mining/hivelord,
/turf/open/floor/mineral/titanium/white/airless,
/area/ruin/space/has_grav)
"E" = (
@@ -57,7 +57,7 @@
/turf/open/floor/mineral/titanium/white/airless,
/area/ruin/space/has_grav)
"S" = (
-/mob/living/simple_animal/hostile/asteroid/hivelord,
+/mob/living/basic/mining/hivelord,
/turf/open/floor/mineral/titanium/white/airless,
/area/ruin/space/has_grav)
"T" = (
diff --git a/_maps/RandomRuins/SpaceRuins/prison_shuttle.dmm b/_maps/RandomRuins/SpaceRuins/prison_shuttle.dmm
index 5aeba75b3bd..6acec2ccc43 100644
--- a/_maps/RandomRuins/SpaceRuins/prison_shuttle.dmm
+++ b/_maps/RandomRuins/SpaceRuins/prison_shuttle.dmm
@@ -56,7 +56,7 @@
/turf/open/floor/plating/airless,
/area/ruin/space/prison_shuttle)
"q" = (
-/mob/living/simple_animal/hostile/asteroid/hivelord,
+/mob/living/basic/mining/hivelord,
/turf/open/misc/asteroid/airless,
/area/ruin/space/prison_shuttle)
"r" = (
@@ -84,7 +84,7 @@
/turf/open/floor/mineral/titanium/tiled/airless,
/area/ruin/space/prison_shuttle)
"w" = (
-/mob/living/simple_animal/hostile/asteroid/hivelord,
+/mob/living/basic/mining/hivelord,
/turf/open/floor/plating/airless,
/area/ruin/space/prison_shuttle)
"x" = (
diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/syndibase.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/syndibase.dmm
index eec3ffec3b3..91d171ca87e 100644
--- a/_maps/RandomRuins/SpaceRuins/skyrat/syndibase.dmm
+++ b/_maps/RandomRuins/SpaceRuins/skyrat/syndibase.dmm
@@ -164,7 +164,7 @@
/turf/open/floor/iron,
/area/ruin/space/has_grav/powered)
"pF" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/turf/open/floor/iron/dark,
/area/ruin/space/has_grav/powered)
"pL" = (
diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/wreckedhomestead.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/wreckedhomestead.dmm
index 3524b7a08a3..98172e42bc5 100644
--- a/_maps/RandomRuins/SpaceRuins/skyrat/wreckedhomestead.dmm
+++ b/_maps/RandomRuins/SpaceRuins/skyrat/wreckedhomestead.dmm
@@ -161,7 +161,7 @@
/turf/open/floor/plating/airless,
/area/ruin/unpowered)
"Az" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/plating/airless,
/area/ruin/unpowered)
diff --git a/_maps/RandomZLevels/SnowCabin.dmm b/_maps/RandomZLevels/SnowCabin.dmm
index cf2b35b3663..cf324e6c5bb 100644
--- a/_maps/RandomZLevels/SnowCabin.dmm
+++ b/_maps/RandomZLevels/SnowCabin.dmm
@@ -426,7 +426,7 @@
/turf/open/floor/iron/white,
/area/awaymission/cabin)
"bF" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/turf/open/floor/iron/white,
/area/awaymission/cabin)
"bG" = (
diff --git a/_maps/RandomZLevels/blackmesa.dmm b/_maps/RandomZLevels/blackmesa.dmm
index b9887279a16..a4aafb74536 100644
--- a/_maps/RandomZLevels/blackmesa.dmm
+++ b/_maps/RandomZLevels/blackmesa.dmm
@@ -5164,7 +5164,7 @@
/turf/open/floor/iron/smooth_large,
/area/awaymission/black_mesa/hecu_zone_external_hall)
"dcv" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/turf/open/floor/iron/smooth_large,
/area/awaymission/black_mesa/xen/acid_lake_building)
"ddi" = (
diff --git a/_maps/RandomZLevels/research.dmm b/_maps/RandomZLevels/research.dmm
index 324734c4eb9..18429389d87 100644
--- a/_maps/RandomZLevels/research.dmm
+++ b/_maps/RandomZLevels/research.dmm
@@ -1042,7 +1042,7 @@
/turf/open/floor/iron/white,
/area/awaymission/research/interior/cryo)
"fc" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/turf/open/floor/iron/white,
/area/awaymission/research/interior/cryo)
"fd" = (
@@ -1083,7 +1083,7 @@
/area/awaymission/research/interior/cryo)
"fh" = (
/obj/effect/decal/cleanable/blood/drip,
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/turf/open/floor/iron/white,
/area/awaymission/research/interior/cryo)
"fk" = (
diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm
index 21b1cddf818..78590312a61 100644
--- a/_maps/map_files/Birdshot/birdshot.dmm
+++ b/_maps/map_files/Birdshot/birdshot.dmm
@@ -104,6 +104,13 @@
/obj/machinery/camera/directional/east,
/turf/open/floor/iron,
/area/station/service/janitor)
+"adl" = (
+/obj/effect/turf_decal/siding/white,
+/obj/machinery/light/small/directional/south,
+/obj/structure/table/reinforced,
+/obj/item/surgery_tray/full/morgue,
+/turf/open/floor/iron/small,
+/area/station/medical/morgue)
"adB" = (
/obj/effect/turf_decal/sand/plating,
/turf/open/floor/plating,
@@ -865,6 +872,12 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/station/engineering/atmos/project)
+"arU" = (
+/obj/effect/turf_decal/bot_white,
+/obj/structure/rack,
+/obj/item/electronics/apc,
+/turf/open/floor/iron/smooth_large,
+/area/station/cargo/warehouse)
"asb" = (
/obj/effect/turf_decal/siding/white,
/turf/open/floor/iron/dark/small,
@@ -1633,6 +1646,10 @@
},
/turf/open/floor/iron/small,
/area/station/maintenance/port/lesser)
+"aJN" = (
+/obj/structure/window/reinforced/shuttle,
+/turf/open/floor/plating,
+/area/station/commons/fitness/recreation/entertainment)
"aJX" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/door/airlock{
@@ -2559,6 +2576,11 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
+"bbP" = (
+/obj/structure/rack,
+/obj/effect/spawner/random/maintenance/two,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"bbU" = (
/obj/effect/landmark/generic_maintenance_landmark,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -3103,6 +3125,14 @@
/mob/living/simple_animal/bot/medbot/autopatrol,
/turf/open/floor/iron/white,
/area/station/medical/medbay/lobby)
+"bmL" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/cable,
+/obj/structure/extinguisher_cabinet/directional/north,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"bmM" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment,
@@ -3296,6 +3326,11 @@
/obj/effect/spawner/random/engineering/atmospherics_portable,
/turf/open/floor/plating,
/area/station/maintenance/department/engine)
+"bqy" = (
+/turf/open/floor/engine{
+ name = "Holodeck Projector Floor"
+ },
+/area/station/holodeck/rec_center)
"bqE" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -5414,14 +5449,6 @@
/obj/structure/sign/poster/official/random/directional/north,
/turf/open/floor/iron/smooth_large,
/area/station/science/auxlab/firing_range)
-"cgD" = (
-/obj/machinery/door/airlock{
- name = "Mineshaft"
- },
-/obj/effect/mapping_helpers/airlock/access/any/service/maintenance,
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/plating/rust,
-/area/station/maintenance/fore/greater)
"cgM" = (
/turf/open/misc/asteroid,
/area/station/maintenance/starboard/greater)
@@ -5497,14 +5524,6 @@
},
/turf/open/floor/iron,
/area/station/maintenance/port/fore)
-"ciL" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/structure/cable,
-/obj/structure/extinguisher_cabinet/directional/north,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"ciR" = (
/obj/structure/table,
/obj/effect/spawner/random/techstorage/command_all,
@@ -7682,6 +7701,12 @@
/obj/effect/spawner/random/structure/steam_vent,
/turf/open/floor/plating,
/area/station/ai_monitored/turret_protected/aisat/maint)
+"cZm" = (
+/obj/effect/landmark/start/hangover,
+/turf/open/floor/engine{
+ name = "Holodeck Projector Floor"
+ },
+/area/station/holodeck/rec_center)
"cZy" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -8386,10 +8411,6 @@
},
/turf/open/floor/plating,
/area/station/maintenance/disposal/incinerator)
-"dmz" = (
-/obj/effect/spawner/random/structure/closet_maintenance,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"dmT" = (
/obj/machinery/camera/directional/north{
c_tag = "Xenobiology - Cell 2";
@@ -8519,6 +8540,11 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/plating,
/area/station/maintenance/department/engine/atmos)
+"doX" = (
+/obj/structure/girder,
+/obj/effect/decal/cleanable/glass/plastitanium,
+/turf/open/floor/plating,
+/area/station/commons/fitness/recreation/entertainment)
"dps" = (
/obj/machinery/camera/directional/south{
c_tag = "AI Chamber - Aft";
@@ -8811,6 +8837,15 @@
/obj/structure/sign/warning/electric_shock,
/turf/closed/wall,
/area/station/maintenance/department/engine)
+"dvs" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/door/firedoor,
+/obj/machinery/door/airlock/glass{
+ name = "Holodeck Access"
+ },
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"dvJ" = (
/obj/structure/table/reinforced,
/obj/effect/turf_decal/tile/dark_red/fourcorners,
@@ -9713,6 +9748,13 @@
/obj/item/wrench,
/turf/open/floor/iron/dark,
/area/station/science/robotics/lab)
+"dNi" = (
+/obj/machinery/power/shuttle_engine/heater{
+ dir = 1
+ },
+/obj/structure/window/spawner/directional/south,
+/turf/open/floor/plating,
+/area/station/commons/fitness/recreation/entertainment)
"dNq" = (
/turf/closed/wall/r_wall/rust,
/area/station/ai_monitored/aisat/exterior)
@@ -10352,6 +10394,12 @@
},
/turf/open/floor/iron/dark,
/area/station/security/lockers)
+"dYf" = (
+/obj/effect/spawner/random/entertainment/arcade{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"dYj" = (
/obj/structure/table,
/obj/effect/turf_decal/tile/dark_red,
@@ -10959,6 +11007,10 @@
/obj/machinery/atmospherics/pipe/layer_manifold/orange/visible,
/turf/open/floor/iron/smooth,
/area/station/engineering/supermatter/room)
+"ejV" = (
+/mob/living/basic/mining/basilisk,
+/turf/open/misc/asteroid,
+/area/space/nearstation)
"eki" = (
/obj/machinery/door/airlock/maintenance{
name = "Maintenance"
@@ -11841,6 +11893,11 @@
},
/turf/open/floor/iron/dark,
/area/station/engineering/break_room)
+"eyz" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
+/obj/structure/chair/stool/directional/west,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"eyB" = (
/obj/structure/cable,
/obj/machinery/door/firedoor,
@@ -12568,6 +12625,11 @@
},
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"eKX" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/mapping_helpers/broken_floor,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"eLn" = (
/obj/machinery/door/airlock/glass{
name = "Gold Standard Law Firm"
@@ -13849,6 +13911,14 @@
},
/turf/open/floor/iron/dark,
/area/station/security/interrogation)
+"fls" = (
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/duct,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/decal/cleanable/glass/plastitanium,
+/turf/open/floor/plating,
+/area/station/maintenance/fore/greater)
"flM" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -17550,6 +17620,14 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/smooth,
/area/station/hallway/secondary/command)
+"gxZ" = (
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/machinery/duct,
+/obj/machinery/power/apc/auto_name/directional/west,
+/turf/open/floor/plating,
+/area/station/maintenance/fore/greater)
"gyd" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/window/spawner/directional/east,
@@ -17879,6 +17957,13 @@
/obj/machinery/airalarm/directional/south,
/turf/open/floor/iron,
/area/station/cargo/office)
+"gEQ" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/chair/sofa/bench/right{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"gFg" = (
/obj/machinery/computer/cargo/request,
/obj/effect/turf_decal/tile/neutral/fourcorners,
@@ -19426,6 +19511,8 @@
/obj/effect/mapping_helpers/broken_floor,
/obj/structure/sign/poster/official/random/directional/north,
/obj/effect/decal/cleanable/dirt,
+/obj/machinery/light/small/directional/north,
+/obj/machinery/camera/directional/west,
/turf/open/floor/iron,
/area/station/commons)
"hem" = (
@@ -20241,16 +20328,6 @@
/obj/effect/turf_decal/stripes/white/line,
/turf/open/floor/plating,
/area/station/cargo/miningoffice)
-"hsK" = (
-/obj/machinery/recycler{
- dir = 8
- },
-/obj/machinery/conveyor{
- dir = 4;
- id = "garbage"
- },
-/turf/open/floor/plating,
-/area/station/service/janitor)
"hsO" = (
/obj/structure/cable,
/obj/effect/spawner/structure/window,
@@ -20689,16 +20766,6 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
-"hzN" = (
-/obj/structure/disposalpipe/segment{
- dir = 6
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/cable,
-/obj/item/radio/intercom/directional/north,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"hzV" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable,
@@ -21023,12 +21090,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/smooth,
/area/station/hallway/secondary/command)
-"hFm" = (
-/obj/effect/turf_decal/bot_white,
-/obj/structure/rack,
-/obj/item/electronics/apc,
-/turf/open/floor/iron/smooth_large,
-/area/station/cargo/warehouse)
"hFx" = (
/turf/open/floor/iron/chapel{
dir = 1
@@ -21174,11 +21235,6 @@
"hJp" = (
/turf/closed/wall/r_wall/rust,
/area/station/ai_monitored/turret_protected/ai)
-"hJr" = (
-/obj/structure/table,
-/obj/effect/decal/cleanable/dirt,
-/turf/open/misc/asteroid,
-/area/station/maintenance/fore/greater)
"hJC" = (
/obj/structure/closet/crate/hydroponics,
/obj/item/paper/guides/jobs/hydroponics,
@@ -22684,11 +22740,6 @@
/obj/effect/spawner/random/engineering/atmospherics_portable,
/turf/open/floor/plating,
/area/station/maintenance/fore/lesser)
-"imd" = (
-/obj/effect/turf_decal/sand/plating,
-/obj/structure/closet/firecloset,
-/turf/open/floor/plating,
-/area/station/maintenance/fore/greater)
"imj" = (
/obj/machinery/door/airlock/security/glass{
id_tag = "permaouter";
@@ -23217,6 +23268,10 @@
},
/turf/closed/wall/mineral/titanium/nodiagonal,
/area/station/engineering/supermatter)
+"iux" = (
+/obj/structure/cable,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"iuH" = (
/obj/machinery/atmospherics/pipe/smart/simple/dark/visible,
/obj/effect/decal/cleanable/dirt,
@@ -23307,8 +23362,9 @@
/turf/open/floor/iron/dark,
/area/station/engineering/atmos)
"ivO" = (
-/obj/effect/turf_decal/sand/plating,
-/obj/structure/reagent_dispensers/fueltank,
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/girder,
+/obj/effect/decal/cleanable/glass/plastitanium,
/turf/open/floor/plating,
/area/station/maintenance/fore/greater)
"ivX" = (
@@ -23730,7 +23786,7 @@
/turf/open/floor/iron/white,
/area/station/medical/medbay/aft)
"iFi" = (
-/obj/effect/spawner/random/structure/crate,
+/obj/effect/spawner/random/vending/colavend,
/turf/open/floor/plating/rust,
/area/station/maintenance/fore/greater)
"iFs" = (
@@ -23815,9 +23871,9 @@
/turf/open/floor/plating,
/area/station/maintenance/fore/lesser)
"iHs" = (
-/obj/effect/turf_decal/sand/plating,
-/obj/effect/spawner/random/engineering/atmospherics_portable,
-/turf/open/floor/plating,
+/obj/machinery/portable_atmospherics/canister/air,
+/obj/effect/mapping_helpers/broken_floor,
+/turf/open/floor/plating/rust,
/area/station/maintenance/fore/greater)
"iHy" = (
/obj/structure/window/reinforced/plasma/spawner/directional/east,
@@ -24135,6 +24191,9 @@
/obj/effect/mapping_helpers/airlock/access/any/security/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"iMy" = (
+/turf/open/misc/asteroid,
+/area/space/nearstation)
"iMC" = (
/obj/machinery/flasher/portable,
/turf/open/floor/plating,
@@ -24353,17 +24412,11 @@
/obj/machinery/airalarm/directional/west,
/turf/open/floor/iron/smooth,
/area/station/engineering/supermatter/room)
-"iQF" = (
-/obj/effect/turf_decal/sand/plating,
-/obj/effect/spawner/random/structure/closet_maintenance,
-/obj/effect/spawner/random/maintenance,
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/plating,
-/area/station/maintenance/fore/greater)
"iQK" = (
/obj/structure/cable,
/obj/effect/decal/cleanable/dirt,
/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/rust,
/area/station/maintenance/fore/greater)
"iQU" = (
@@ -24384,6 +24437,8 @@
"iRv" = (
/obj/structure/cable,
/obj/effect/decal/cleanable/dirt,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/decal/cleanable/glass/plastitanium,
/turf/open/floor/plating,
/area/station/maintenance/fore/greater)
"iRz" = (
@@ -24428,15 +24483,6 @@
"iSr" = (
/turf/open/floor/iron,
/area/station/security/execution/transfer)
-"iSB" = (
-/obj/structure/cable,
-/obj/machinery/door/airlock{
- name = "Maintenance"
- },
-/obj/effect/mapping_helpers/airlock/access/any/service/maintenance,
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/plating,
-/area/station/maintenance/fore/greater)
"iSK" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -24445,13 +24491,6 @@
/obj/structure/sign/warning/pods/directional/west,
/turf/open/floor/iron/checker,
/area/station/security/breakroom)
-"iSO" = (
-/obj/structure/cable,
-/obj/machinery/power/apc/auto_name/directional/north,
-/obj/effect/decal/cleanable/dirt,
-/obj/machinery/duct,
-/turf/open/floor/plating,
-/area/station/maintenance/fore/greater)
"iSW" = (
/obj/structure/rack,
/obj/item/clothing/gloves/boxing/yellow,
@@ -24991,8 +25030,13 @@
/turf/open/floor/plating,
/area/station/command/heads_quarters/rd)
"jbm" = (
-/turf/closed/mineral/random/stationside,
-/area/station/maintenance/fore/greater)
+/obj/machinery/firealarm/directional/south,
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/broken_flooring/corner/directional/north,
+/obj/structure/sign/poster/official/random/directional/west,
+/obj/effect/spawner/random/vending/snackvend,
+/turf/open/floor/plating,
+/area/station/commons/fitness/recreation/entertainment)
"jbr" = (
/obj/structure/table/glass,
/obj/item/folder/blue{
@@ -25110,15 +25154,15 @@
/turf/open/floor/plating/rust,
/area/station/maintenance/fore/greater)
"jey" = (
-/obj/structure/cable,
-/obj/machinery/portable_atmospherics/pump,
-/turf/open/floor/plating/rust,
-/area/station/maintenance/fore/greater)
+/obj/machinery/vending/clothing,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"jez" = (
-/obj/structure/cable,
-/obj/machinery/portable_atmospherics/canister/air,
-/turf/open/floor/plating,
-/area/station/maintenance/fore/greater)
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"jeC" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -25147,11 +25191,12 @@
/turf/open/floor/plating,
/area/station/medical/medbay/lobby)
"jeX" = (
-/obj/structure/cable,
-/obj/machinery/portable_atmospherics/canister/air,
+/obj/machinery/light/small/directional/east,
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/plating/rust,
-/area/station/maintenance/fore/greater)
+/obj/effect/mapping_helpers/broken_floor,
+/obj/structure/broken_flooring/singular/directional/west,
+/turf/open/floor/plating,
+/area/station/commons/fitness/recreation/entertainment)
"jfs" = (
/obj/effect/turf_decal/tile/yellow/half/contrasted{
dir = 4
@@ -25794,10 +25839,6 @@
/obj/machinery/light/small/directional/west,
/turf/open/floor/iron/smooth_large,
/area/station/science/auxlab/firing_range)
-"jsn" = (
-/obj/effect/turf_decal/sand/plating,
-/turf/open/floor/plating,
-/area/station/maintenance/fore/greater)
"jsv" = (
/obj/structure/cable,
/obj/machinery/holopad,
@@ -26171,12 +26212,6 @@
},
/turf/open/floor/iron/kitchen/small,
/area/station/hallway/secondary/service)
-"jzl" = (
-/obj/structure/cable,
-/obj/effect/turf_decal/sand/plating,
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/plating,
-/area/station/maintenance/fore/greater)
"jzo" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -26225,7 +26260,9 @@
/area/station/hallway/secondary/construction)
"jAs" = (
/obj/structure/cable,
-/obj/effect/turf_decal/sand/plating,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/spawner/random/structure/closet_maintenance,
+/obj/effect/spawner/random/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/fore/greater)
"jAw" = (
@@ -26522,6 +26559,15 @@
/obj/structure/sign/poster/official/random/directional/north,
/turf/open/floor/iron/smooth,
/area/station/hallway/secondary/command)
+"jFc" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/item/trash/cheesie{
+ pixel_x = 7;
+ pixel_y = 3
+ },
+/obj/structure/table,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"jFf" = (
/obj/effect/turf_decal/tile/green/diagonal_centre,
/obj/machinery/status_display/ai/directional/north,
@@ -27175,6 +27221,13 @@
/obj/effect/spawner/structure/window/reinforced/tinted,
/turf/open/floor/plating,
/area/station/maintenance/fore/greater)
+"jPr" = (
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/duct,
+/obj/effect/mapping_helpers/broken_floor,
+/turf/open/floor/plating,
+/area/station/maintenance/fore/greater)
"jQo" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/door/airlock/research/glass{
@@ -27469,6 +27522,10 @@
dir = 8
},
/area/station/hallway/secondary/dock)
+"jWR" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"jWZ" = (
/obj/machinery/mineral/ore_redemption{
dir = 4;
@@ -27531,15 +27588,6 @@
/obj/effect/turf_decal/siding/wideplating/dark/corner,
/turf/open/floor/iron,
/area/station/security)
-"jXE" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/structure/cable,
-/obj/machinery/light/cold/directional/north,
-/obj/structure/sign/poster/official/random/directional/north,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"jXQ" = (
/obj/structure/flora/bush/large/style_random{
pixel_x = -18;
@@ -28303,6 +28351,15 @@
/obj/machinery/light/small/directional/east,
/turf/open/floor/carpet/orange,
/area/station/service/abandoned_gambling_den)
+"kmb" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/computer/holodeck{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"kmd" = (
/obj/structure/cable,
/obj/machinery/door/airlock/external{
@@ -28367,6 +28424,12 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/orange/hidden/layer1,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos)
+"kmS" = (
+/obj/machinery/power/shuttle_engine/propulsion{
+ dir = 1
+ },
+/turf/open/floor/plating,
+/area/station/commons/fitness/recreation/entertainment)
"kmT" = (
/obj/structure/closet/firecloset,
/turf/open/floor/plating,
@@ -28381,6 +28444,14 @@
},
/turf/open/floor/iron,
/area/station/cargo/storage)
+"knt" = (
+/obj/effect/turf_decal/stripes/corner{
+ dir = 1
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/broken_flooring/pile/directional/east,
+/turf/open/floor/plating,
+/area/station/maintenance/hallway/abandoned_command)
"knv" = (
/turf/closed/wall,
/area/station/maintenance/department/engine/atmos)
@@ -28766,6 +28837,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/dark,
/area/station/cargo/office)
+"ktN" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/chair/sofa/bench/left{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"ktZ" = (
/obj/effect/turf_decal/sand/plating,
/obj/structure/bookcase/random,
@@ -29222,6 +29300,7 @@
"kDq" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/commons)
"kDV" = (
@@ -29370,8 +29449,7 @@
},
/area/station/maintenance/department/engine/atmos)
"kGz" = (
-/obj/effect/mapping_helpers/broken_floor,
-/obj/structure/reagent_dispensers/plumbed,
+/obj/structure/girder,
/turf/open/floor/plating,
/area/station/maintenance/fore/greater)
"kGB" = (
@@ -29665,11 +29743,6 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/turf/open/floor/iron/showroomfloor,
/area/station/commons/toilet/restrooms)
-"kKN" = (
-/obj/structure/barricade/wooden,
-/obj/effect/decal/cleanable/dirt,
-/turf/open/misc/asteroid,
-/area/station/maintenance/fore/greater)
"kKT" = (
/obj/machinery/computer/camera_advanced/xenobio{
dir = 4
@@ -29724,6 +29797,10 @@
dir = 1
},
/area/station/medical/treatment_center)
+"kLT" = (
+/obj/machinery/rnd/bepis,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"kMm" = (
/obj/structure/chair/sofa/right/brown{
dir = 1
@@ -29866,6 +29943,10 @@
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
/area/station/construction/mining/aux_base)
+"kOW" = (
+/obj/effect/mob_spawn/corpse/human/miner,
+/turf/open/misc/asteroid,
+/area/space/nearstation)
"kPa" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -30353,11 +30434,10 @@
/turf/open/floor/grass,
/area/station/cargo/storage)
"kZf" = (
-/obj/effect/turf_decal/sand/plating,
+/obj/structure/cable,
/obj/effect/decal/cleanable/dirt,
-/obj/effect/spawner/random/trash,
-/turf/open/floor/plating,
-/area/station/maintenance/fore/greater)
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"kZh" = (
/obj/structure/table/glass,
/obj/effect/turf_decal/siding/thinplating_new/light{
@@ -30368,10 +30448,11 @@
/area/station/science/cubicle)
"kZo" = (
/obj/structure/cable,
-/obj/effect/turf_decal/sand/plating,
/obj/effect/decal/cleanable/dirt,
/obj/machinery/duct,
/obj/effect/spawner/random/trash,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/maintenance/fore/greater)
"kZx" = (
@@ -31353,10 +31434,6 @@
/obj/structure/ore_box,
/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
-"lnT" = (
-/obj/machinery/rnd/bepis,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"lnZ" = (
/obj/effect/turf_decal/tile/dark_red,
/obj/effect/decal/cleanable/dirt,
@@ -31469,8 +31546,10 @@
/turf/open/floor/wood/parquet,
/area/station/service/library)
"lqs" = (
-/turf/closed/wall/rust,
-/area/station/maintenance/fore/greater)
+/obj/machinery/light/cold/directional/south,
+/obj/structure/reagent_dispensers/water_cooler,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"lqt" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -32920,12 +32999,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron,
/area/station/security/prison/rec)
-"lPG" = (
-/obj/machinery/vending/clothing,
-/obj/machinery/camera/directional/north,
-/obj/machinery/light/small/directional/north,
-/turf/open/floor/iron,
-/area/station/commons)
"lPI" = (
/obj/effect/turf_decal/siding/wood{
dir = 8
@@ -32937,6 +33010,16 @@
/obj/machinery/announcement_system,
/turf/open/floor/iron/grimy,
/area/station/tcommsat/server)
+"lPO" = (
+/obj/structure/table,
+/obj/item/surgery_tray/full{
+ pixel_y = -5
+ },
+/obj/item/wirecutters{
+ pixel_y = 8
+ },
+/turf/open/floor/iron/dark/small,
+/area/station/security/execution/education)
"lPR" = (
/obj/structure/table,
/obj/effect/spawner/random/maintenance,
@@ -33796,6 +33879,14 @@
dir = 4
},
/area/station/hallway/secondary/entry)
+"meP" = (
+/obj/machinery/airalarm/directional/west,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/entertainment/arcade{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"mfc" = (
/obj/effect/turf_decal/tile/red/opposingcorners,
/obj/effect/turf_decal/tile/blue/opposingcorners{
@@ -35273,6 +35364,9 @@
/obj/item/radio/intercom/directional/west,
/turf/open/floor/iron/white/small,
/area/station/medical/virology)
+"mHq" = (
+/turf/closed/wall/r_wall,
+/area/station/commons/fitness/recreation/entertainment)
"mHZ" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -35543,11 +35637,6 @@
},
/turf/open/floor/iron,
/area/station/security/processing)
-"mLx" = (
-/obj/structure/rack,
-/obj/effect/spawner/random/maintenance/two,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"mLA" = (
/obj/structure/cable,
/obj/machinery/power/apc/auto_name/directional/west,
@@ -36004,6 +36093,11 @@
/obj/effect/decal/cleanable/cobweb/cobweb2,
/turf/open/floor/iron/grimy,
/area/station/cargo/boutique)
+"mUC" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/chair/stool/directional/west,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"mUO" = (
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
@@ -36375,6 +36469,16 @@
/obj/structure/alien/weeds,
/turf/open/floor/wood,
/area/station/maintenance/starboard/greater)
+"ncf" = (
+/obj/machinery/recycler{
+ dir = 8
+ },
+/obj/machinery/conveyor{
+ dir = 4;
+ id = "garbage"
+ },
+/turf/open/floor/plating,
+/area/station/service/janitor)
"ncl" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -36449,10 +36553,6 @@
},
/turf/open/floor/wood/tile,
/area/station/commons/vacant_room/commissary)
-"net" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/commons)
"neZ" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -38330,6 +38430,15 @@
/obj/effect/turf_decal/stripes/red/line,
/turf/open/floor/iron/small,
/area/station/hallway/primary/central/fore)
+"nMX" = (
+/obj/machinery/camera/directional/south{
+ c_tag = "Holodeck - Aft";
+ name = "holodeck camera"
+ },
+/turf/open/floor/engine{
+ name = "Holodeck Projector Floor"
+ },
+/area/station/holodeck/rec_center)
"nNb" = (
/obj/structure/disposalpipe/segment{
dir = 6
@@ -38553,6 +38662,11 @@
},
/turf/open/floor/plating,
/area/station/command/bridge)
+"nRo" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/table,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"nRr" = (
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
@@ -39637,6 +39751,13 @@
/obj/item/radio/intercom/directional/east,
/turf/open/floor/iron/dark/small,
/area/station/medical/chemistry)
+"onI" = (
+/obj/machinery/door/airlock/maintenance{
+ name = "Maintenance"
+ },
+/obj/effect/mapping_helpers/airlock/access/all/supply/general,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"onP" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/door/firedoor,
@@ -39934,6 +40055,11 @@
},
/turf/open/floor/iron,
/area/station/hallway/secondary/recreation)
+"ott" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/trash,
+/turf/open/floor/plating,
+/area/station/maintenance/fore/greater)
"otG" = (
/obj/structure/filingcabinet/filingcabinet,
/obj/machinery/status_display/supply{
@@ -40456,6 +40582,13 @@
/obj/effect/mapping_helpers/airlock/access/any/service/hydroponics,
/turf/open/floor/plating,
/area/station/maintenance/port/greater)
+"oDO" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"oDS" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/firealarm/directional/south,
@@ -40470,10 +40603,6 @@
/obj/effect/landmark/start/assistant,
/turf/open/floor/iron,
/area/station/commons/dorms)
-"oEm" = (
-/obj/structure/barricade/wooden,
-/turf/open/misc/asteroid,
-/area/station/maintenance/fore/greater)
"oEr" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -41427,6 +41556,16 @@
/obj/machinery/atmospherics/pipe/heat_exchanging/simple,
/turf/open/floor/iron/dark/small,
/area/station/tcommsat/server)
+"oXa" = (
+/obj/structure/disposalpipe/segment{
+ dir = 6
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/cable,
+/obj/item/radio/intercom/directional/north,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"oXe" = (
/obj/effect/mapping_helpers/broken_floor,
/obj/machinery/duct,
@@ -42789,10 +42928,11 @@
/turf/open/floor/iron/diagonal,
/area/station/command/heads_quarters/hop)
"puC" = (
-/obj/effect/turf_decal/sand/plating,
+/obj/machinery/light/small/directional/west,
/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/plating,
-/area/station/maintenance/fore/greater)
+/obj/structure/closet/firecloset,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"puD" = (
/obj/structure/bookcase/random/nonfiction,
/obj/machinery/newscaster/directional/west,
@@ -43069,6 +43209,9 @@
/obj/machinery/camera/autoname/directional/north,
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
+"pzd" = (
+/turf/closed/wall,
+/area/station/commons/fitness/recreation/entertainment)
"pzn" = (
/obj/structure/table,
/obj/effect/turf_decal/siding/wood{
@@ -43573,6 +43716,12 @@
/obj/machinery/light_switch/directional/north,
/turf/open/floor/wood,
/area/station/commons/fitness/recreation)
+"pGX" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron,
+/area/station/commons)
"pHe" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/door/firedoor,
@@ -43847,11 +43996,6 @@
},
/turf/open/floor/iron/small,
/area/station/ai_monitored/command/storage/eva)
-"pLk" = (
-/mob/living/basic/mining/basilisk,
-/obj/effect/decal/cleanable/dirt,
-/turf/open/misc/asteroid,
-/area/station/maintenance/fore/greater)
"pLl" = (
/obj/effect/spawner/random/vending/snackvend,
/obj/effect/turf_decal/tile/red/opposingcorners{
@@ -44074,6 +44218,14 @@
/obj/machinery/duct,
/turf/open/floor/iron/kitchen/small,
/area/station/hallway/secondary/service)
+"pOL" = (
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/decal/cleanable/glass/plastitanium,
+/turf/open/floor/plating,
+/area/station/maintenance/fore/greater)
"pOX" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 1
@@ -44222,6 +44374,12 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/department/prison)
+"pSf" = (
+/obj/machinery/power/apc/auto_name/directional/west,
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"pSm" = (
/obj/effect/mapping_helpers/broken_floor,
/obj/effect/turf_decal/tile/yellow/anticorner/contrasted{
@@ -44329,16 +44487,6 @@
/obj/effect/mapping_helpers/airlock/access/all/service/chapel_office,
/turf/open/floor/plating,
/area/station/maintenance/port/lesser)
-"pTr" = (
-/obj/structure/table,
-/obj/item/surgery_tray/full{
- pixel_y = -5
- },
-/obj/item/wirecutters{
- pixel_y = 8
- },
-/turf/open/floor/iron/dark/small,
-/area/station/security/execution/education)
"pTs" = (
/obj/structure/window/spawner/directional/west,
/obj/structure/chair/sofa/corp/right{
@@ -44462,6 +44610,11 @@
/obj/machinery/firealarm/directional/west,
/turf/open/floor/iron/white,
/area/station/science/auxlab/firing_range)
+"pVo" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/girder,
+/turf/open/floor/plating,
+/area/station/maintenance/fore/greater)
"pVq" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/turf_decal/trimline/neutral/line{
@@ -46068,10 +46221,6 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/commons/dorms)
-"quf" = (
-/obj/item/kirbyplants/random,
-/turf/open/floor/iron,
-/area/station/commons)
"qui" = (
/obj/machinery/camera/autoname/directional/north,
/turf/open/floor/wood/parquet,
@@ -46238,6 +46387,13 @@
},
/turf/open/floor/iron/solarpanel/airless,
/area/station/solars/port)
+"qxf" = (
+/obj/machinery/cryo_cell,
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/turf/open/floor/iron/small,
+/area/station/medical/cryo)
"qxh" = (
/obj/structure/disposalpipe/segment{
dir = 6
@@ -46530,6 +46686,15 @@
/obj/structure/barricade/wooden/crude,
/turf/open/floor/plating,
/area/station/cargo/boutique)
+"qBl" = (
+/obj/machinery/camera/directional/north{
+ c_tag = "Holodeck - Fore";
+ name = "holodeck camera"
+ },
+/turf/open/floor/engine{
+ name = "Holodeck Projector Floor"
+ },
+/area/station/holodeck/rec_center)
"qBy" = (
/obj/effect/turf_decal/plaque{
icon_state = "L5"
@@ -49163,6 +49328,10 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/security/armory)
+"rtK" = (
+/obj/item/kirbyplants/random,
+/turf/open/floor/iron,
+/area/station/commons)
"rtQ" = (
/turf/closed/wall/r_wall,
/area/station/security/tram)
@@ -49186,14 +49355,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/station/science/lower)
-"ruC" = (
-/obj/structure/window/reinforced/spawner/directional/east,
-/obj/effect/turf_decal/tile/green/anticorner/contrasted,
-/obj/structure/table/glass,
-/obj/effect/mapping_helpers/broken_floor,
-/obj/item/radio/intercom/directional/south,
-/turf/open/floor/iron/white,
-/area/station/medical/virology)
"ruD" = (
/turf/open/floor/plating,
/area/station/maintenance/starboard/lesser)
@@ -49510,6 +49671,11 @@
dir = 1
},
/area/station/hallway/secondary/entry)
+"rzR" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/holopad,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"rAb" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -49751,6 +49917,11 @@
dir = 4
},
/area/station/hallway/secondary/entry)
+"rDl" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/digital_clock/directional/north,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"rDx" = (
/obj/effect/turf_decal/tile/neutral/fourcorners,
/obj/structure/window/reinforced/spawner/directional/south,
@@ -49987,13 +50158,9 @@
/turf/open/floor/iron/white,
/area/station/medical/virology)
"rGL" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/item/picket_sign{
- desc = "Can't you read? it clearly says what it says!";
- name = "DO NOT ENTER"
- },
-/turf/open/misc/asteroid,
-/area/station/maintenance/fore/greater)
+/obj/effect/spawner/structure/window/reinforced,
+/turf/open/floor/plating,
+/area/station/commons/fitness/recreation/entertainment)
"rGN" = (
/obj/effect/spawner/random/structure/crate,
/turf/open/floor/plating,
@@ -50110,9 +50277,9 @@
/turf/open/floor/engine,
/area/station/engineering/gravity_generator)
"rIO" = (
-/obj/effect/spawner/random/trash,
-/turf/open/misc/asteroid,
-/area/station/maintenance/fore/greater)
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"rIS" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/turf/open/floor/iron/cafeteria,
@@ -50399,6 +50566,16 @@
/obj/effect/spawner/random/entertainment/arcade,
/turf/open/floor/iron/cafeteria,
/area/station/security/prison/mess)
+"rNK" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/door/firedoor,
+/obj/machinery/door/airlock/glass{
+ name = "Holodeck"
+ },
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"rOb" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -51012,6 +51189,10 @@
/obj/structure/reagent_dispensers/watertank,
/turf/open/floor/plating,
/area/station/maintenance/port/greater)
+"rXy" = (
+/obj/effect/spawner/random/structure/closet_maintenance,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"rXW" = (
/obj/structure/flora/bush/flowers_yw,
/obj/machinery/door/window/left/directional/west{
@@ -51122,14 +51303,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
-"rZu" = (
-/obj/effect/turf_decal/stripes/corner{
- dir = 1
- },
-/obj/effect/decal/cleanable/dirt,
-/obj/structure/broken_flooring/pile/directional/east,
-/turf/open/floor/plating,
-/area/station/maintenance/hallway/abandoned_command)
"rZG" = (
/obj/structure/closet/crate/trashcart,
/obj/effect/spawner/random/trash/food_packaging,
@@ -51766,11 +51939,6 @@
/obj/machinery/camera/autoname/directional/west,
/turf/open/floor/iron,
/area/station/medical/chemistry)
-"skH" = (
-/obj/structure/rack,
-/obj/item/flashlight/lantern,
-/turf/open/misc/asteroid,
-/area/station/maintenance/fore/greater)
"skP" = (
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
@@ -52973,6 +53141,10 @@
/obj/effect/turf_decal/tile/neutral/opposingcorners,
/turf/open/floor/iron,
/area/station/hallway/secondary/spacebridge)
+"sEi" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"sEn" = (
/obj/item/clothing/head/cone,
/obj/item/clothing/head/cone{
@@ -53707,6 +53879,12 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/cargo/storage)
+"sSl" = (
+/obj/machinery/camera/directional/west,
+/obj/machinery/status_display/ai/directional/west,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"sSm" = (
/obj/effect/turf_decal/stripes/red/line{
dir = 4
@@ -54326,10 +54504,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/hallway/secondary/entry)
-"tbM" = (
-/obj/effect/spawner/random/structure/closet_maintenance,
-/turf/open/misc/asteroid,
-/area/station/maintenance/fore/greater)
"tbS" = (
/obj/structure/disposalpipe/segment,
/obj/effect/turf_decal/tile/neutral/fourcorners,
@@ -54596,13 +54770,6 @@
/obj/structure/sign/poster/official/random/directional/north,
/turf/open/floor/wood/tile,
/area/station/command/heads_quarters/hop)
-"tgJ" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell,
-/obj/effect/turf_decal/stripes/line{
- dir = 4
- },
-/turf/open/floor/iron/small,
-/area/station/medical/cryo)
"tgR" = (
/obj/structure/disposalpipe/junction/flip{
dir = 1
@@ -55371,13 +55538,6 @@
},
/turf/open/space/basic,
/area/space/nearstation)
-"twh" = (
-/obj/effect/turf_decal/sand/plating,
-/obj/effect/decal/cleanable/dirt,
-/obj/structure/table,
-/obj/item/stack/sheet/mineral/sandstone,
-/turf/open/floor/plating,
-/area/station/maintenance/fore/greater)
"twi" = (
/obj/structure/disposalpipe/segment,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -55458,8 +55618,12 @@
/turf/open/floor/iron/small,
/area/station/hallway/primary/central/fore)
"twN" = (
-/obj/effect/decal/cleanable/dirt,
-/turf/open/misc/asteroid,
+/obj/machinery/door/airlock{
+ name = "Maintenance"
+ },
+/obj/effect/mapping_helpers/airlock/access/any/service/maintenance,
+/obj/structure/cable,
+/turf/open/floor/plating/rust,
/area/station/maintenance/fore/greater)
"twR" = (
/obj/structure/table/glass,
@@ -55851,13 +56015,6 @@
/obj/machinery/shower/directional/west,
/turf/open/floor/iron/dark,
/area/station/medical/pharmacy)
-"tDm" = (
-/obj/machinery/door/airlock/maintenance{
- name = "Maintenance"
- },
-/obj/effect/mapping_helpers/airlock/access/all/supply/general,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"tDn" = (
/turf/closed/wall/r_wall,
/area/station/maintenance/department/prison)
@@ -56124,6 +56281,9 @@
/obj/effect/turf_decal/tile/green/diagonal_centre,
/turf/open/floor/iron/diagonal,
/area/station/hallway/primary/central/aft)
+"tIE" = (
+/turf/closed/wall/mineral/titanium,
+/area/station/commons/fitness/recreation/entertainment)
"tII" = (
/obj/effect/spawner/random/structure/closet_maintenance,
/turf/open/floor/plating,
@@ -56137,6 +56297,11 @@
/obj/effect/turf_decal/tile/green/diagonal_centre,
/turf/open/floor/iron/diagonal,
/area/station/hallway/primary/central/aft)
+"tIQ" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/structure/crate,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"tJe" = (
/obj/effect/turf_decal/tile/dark_red/half/contrasted{
dir = 1
@@ -56209,6 +56374,10 @@
/obj/effect/turf_decal/tile/green/diagonal_centre,
/turf/open/floor/iron/diagonal,
/area/station/hallway/primary/central/aft)
+"tJN" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"tJO" = (
/obj/effect/spawner/structure/window/reinforced/plasma,
/obj/machinery/atmospherics/pipe/smart/simple/brown/visible,
@@ -56604,6 +56773,17 @@
/obj/structure/extinguisher_cabinet/directional/east,
/turf/open/floor/iron,
/area/station/security/courtroom)
+"tRp" = (
+/obj/machinery/door/firedoor,
+/obj/machinery/door/airlock/public/glass{
+ name = "Holodeck Door"
+ },
+/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
+ cycle_id = "holodeck"
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"tRw" = (
/obj/structure/disposalpipe/trunk{
dir = 8
@@ -57977,8 +58157,7 @@
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
"unK" = (
-/obj/structure/rack,
-/obj/effect/spawner/random/maintenance,
+/obj/structure/reagent_dispensers/fueltank,
/turf/open/floor/plating,
/area/station/maintenance/fore/greater)
"unM" = (
@@ -59235,6 +59414,11 @@
},
/turf/open/floor/iron/showroomfloor,
/area/station/commons/toilet/auxiliary)
+"uJZ" = (
+/obj/structure/window/reinforced/shuttle,
+/obj/structure/window/reinforced/shuttle,
+/turf/open/floor/plating,
+/area/station/commons/fitness/recreation/entertainment)
"uKl" = (
/obj/effect/turf_decal/tile/neutral{
dir = 1
@@ -59333,13 +59517,6 @@
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
/area/station/hallway/secondary/service)
-"uMl" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell,
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/turf/open/floor/iron/small,
-/area/station/medical/cryo)
"uMu" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -59893,6 +60070,11 @@
},
/turf/closed/wall,
/area/station/hallway/primary/starboard)
+"uWg" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/structure/sign/poster/official/random/directional/west,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"uWl" = (
/obj/structure/disposalpipe/segment{
dir = 10
@@ -60641,13 +60823,6 @@
/obj/structure/closet/emcloset,
/turf/open/floor/iron/small,
/area/station/maintenance/starboard/central)
-"viR" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/structure/sink/directional/south,
-/obj/item/reagent_containers/cup/bucket,
-/obj/item/mop,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"viT" = (
/obj/machinery/light/cold/directional/east,
/turf/open/floor/iron,
@@ -60939,6 +61114,14 @@
/obj/effect/spawner/random/trash,
/turf/open/floor/plating,
/area/station/maintenance/port/greater)
+"vmA" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 1
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"vmH" = (
/obj/machinery/door/morgue{
name = "Confession Booth (Chaplain)";
@@ -61260,18 +61443,6 @@
},
/turf/open/floor/catwalk_floor/iron_dark,
/area/station/tcommsat/server)
-"vra" = (
-/obj/effect/turf_decal/sand/plating,
-/obj/effect/decal/cleanable/dirt,
-/obj/structure/table,
-/obj/item/clothing/under/rank/cargo/miner/lavaland{
- pixel_y = 3
- },
-/obj/item/clothing/suit/hooded/wintercoat/miner{
- pixel_y = 5
- },
-/turf/open/floor/plating,
-/area/station/maintenance/fore/greater)
"vrf" = (
/obj/structure/hedge,
/obj/machinery/light/small/directional/north,
@@ -62344,6 +62515,12 @@
},
/turf/open/floor/iron/small,
/area/station/hallway/primary/central/fore)
+"vIN" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/item/chair/stool,
+/obj/structure/sign/poster/contraband/random/directional/north,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"vIX" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -62638,11 +62815,6 @@
/obj/machinery/portable_atmospherics/canister/air,
/turf/open/floor/plating,
/area/station/maintenance/central/greater)
-"vMS" = (
-/obj/item/pickaxe,
-/obj/effect/decal/cleanable/dirt,
-/turf/open/misc/asteroid,
-/area/station/maintenance/fore/greater)
"vMT" = (
/obj/machinery/hydroponics/soil,
/obj/item/food/grown/mushroom/libertycap,
@@ -63033,10 +63205,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/white/small,
/area/station/service/hydroponics)
-"vTO" = (
-/mob/living/simple_animal/hostile/asteroid/gutlunch,
-/turf/open/misc/asteroid,
-/area/station/maintenance/fore/greater)
"vTV" = (
/turf/closed/wall/r_wall,
/area/station/command/heads_quarters/hos)
@@ -63917,10 +64085,6 @@
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
/area/station/hallway/secondary/exit/departure_lounge)
-"whS" = (
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"whX" = (
/obj/structure/disposalpipe/segment,
/obj/machinery/door/airlock{
@@ -64107,6 +64271,13 @@
/obj/effect/spawner/structure/window/reinforced/tinted,
/turf/open/floor/plating,
/area/station/hallway/secondary/recreation)
+"wkZ" = (
+/obj/machinery/cryo_cell,
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/turf/open/floor/iron/small,
+/area/station/medical/cryo)
"wla" = (
/turf/open/floor/iron/chapel,
/area/station/maintenance/starboard/greater)
@@ -65196,6 +65367,11 @@
/obj/machinery/computer/arcade/orion_trail/kobayashi,
/turf/open/floor/wood/tile,
/area/station/maintenance/port/lesser)
+"wCD" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"wCH" = (
/obj/effect/turf_decal/stripes/white/line{
dir = 9
@@ -65541,6 +65717,14 @@
/obj/structure/window/reinforced/spawner/directional/north,
/turf/open/space/basic,
/area/space/nearstation)
+"wIG" = (
+/obj/structure/window/reinforced/spawner/directional/east,
+/obj/effect/turf_decal/tile/green/anticorner/contrasted,
+/obj/structure/table/glass,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/item/radio/intercom/directional/south,
+/turf/open/floor/iron/white,
+/area/station/medical/virology)
"wII" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/orange/hidden/layer1,
/turf/open/floor/iron/dark,
@@ -66292,11 +66476,6 @@
/obj/machinery/door/firedoor,
/turf/open/floor/iron/textured_half,
/area/station/security/prison/work)
-"wTn" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/spawner/random/structure/crate,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"wTs" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/sign/poster/official/random/directional/north,
@@ -66832,6 +67011,14 @@
/obj/structure/grille,
/turf/closed/wall/mineral/titanium/nodiagonal,
/area/station/engineering/atmos)
+"xaj" = (
+/obj/machinery/light/cold/directional/west,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/entertainment/arcade{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"xam" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -67391,6 +67578,13 @@
"xia" = (
/turf/closed/wall,
/area/station/science/cubicle)
+"xic" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/sink/directional/south,
+/obj/item/reagent_containers/cup/bucket,
+/obj/item/mop,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"xif" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -68646,6 +68840,15 @@
},
/turf/open/floor/iron/dark,
/area/station/security/interrogation)
+"xyz" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/cable,
+/obj/machinery/light/cold/directional/north,
+/obj/structure/sign/poster/official/random/directional/north,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"xyJ" = (
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron,
@@ -69163,11 +69366,6 @@
/obj/item/reagent_containers/cup/glass/drinkingglass,
/turf/open/floor/iron/cafeteria,
/area/station/security/prison/mess)
-"xGS" = (
-/obj/effect/turf_decal/sand/plating,
-/obj/structure/reagent_dispensers/watertank,
-/turf/open/floor/plating,
-/area/station/maintenance/fore/greater)
"xGT" = (
/obj/effect/turf_decal/tile/dark_red/opposingcorners,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
@@ -70044,6 +70242,11 @@
/obj/structure/barricade/wooden/crude,
/turf/open/floor/plating,
/area/station/service/abandoned_gambling_den/gaming)
+"xRX" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/trash/graffiti,
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"xRZ" = (
/obj/effect/turf_decal/siding/wood,
/turf/open/floor/grass,
@@ -70712,13 +70915,6 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron,
/area/station/hallway/secondary/exit/departure_lounge)
-"yaJ" = (
-/obj/effect/turf_decal/siding/white,
-/obj/machinery/light/small/directional/south,
-/obj/structure/table/reinforced,
-/obj/item/surgery_tray/full/morgue,
-/turf/open/floor/iron/small,
-/area/station/medical/morgue)
"yaL" = (
/turf/closed/wall,
/area/station/commons/vacant_room/commissary)
@@ -70849,24 +71045,6 @@
/obj/effect/turf_decal/stripes/white/line,
/turf/open/floor/noslip/tram_plate,
/area/station/maintenance/department/medical/central)
-"ycz" = (
-/obj/effect/turf_decal/sand/plating,
-/obj/effect/decal/cleanable/dirt,
-/obj/structure/table,
-/obj/item/stack/sheet/mineral/coal{
- pixel_x = 6;
- pixel_y = 13
- },
-/obj/item/stack/sheet/mineral/coal{
- pixel_x = 1;
- pixel_y = 8
- },
-/obj/item/stack/sheet/mineral/coal{
- pixel_x = -2;
- pixel_y = -1
- },
-/turf/open/floor/plating,
-/area/station/maintenance/fore/greater)
"ycC" = (
/turf/closed/wall/r_wall,
/area/station/command/bridge)
@@ -70910,8 +71088,15 @@
/turf/open/floor/wood/tile,
/area/station/command/bridge)
"ydt" = (
-/turf/open/misc/asteroid,
-/area/station/maintenance/fore/greater)
+/obj/machinery/door/firedoor,
+/obj/machinery/door/airlock/public/glass{
+ name = "Holodeck Door"
+ },
+/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
+ cycle_id = "holodeck"
+ },
+/turf/open/floor/iron,
+/area/station/commons/fitness/recreation/entertainment)
"ydu" = (
/obj/structure/cable,
/obj/structure/disposalpipe/sorting/mail{
@@ -70940,6 +71125,11 @@
"yea" = (
/turf/closed/wall,
/area/station/service/chapel/office)
+"yec" = (
+/obj/structure/girder,
+/obj/effect/decal/cleanable/glass/plastitanium,
+/turf/open/floor/plating,
+/area/station/maintenance/fore/greater)
"yee" = (
/obj/item/kirbyplants/random,
/obj/machinery/light_switch/directional/west,
@@ -71137,9 +71327,6 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/station/maintenance/department/science/xenobiology)
-"yfX" = (
-/turf/open/floor/plating/rust,
-/area/station/maintenance/fore/greater)
"yfY" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -71440,6 +71627,7 @@
"yju" = (
/obj/effect/spawner/random/structure/closet_maintenance,
/obj/effect/spawner/random/maintenance,
+/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/maintenance/fore/greater)
"yjD" = (
@@ -83003,7 +83191,7 @@ uzJ
mQh
nJU
ppk
-lnT
+kLT
ovQ
oRr
poM
@@ -83504,14 +83692,14 @@ gOK
slY
hfc
slY
-viR
+xic
jBb
kPW
kwY
-whS
-dmz
+sEi
+rXy
slY
-hzN
+oXa
lRc
moz
kee
@@ -83761,14 +83949,14 @@ gPN
gZk
iNE
ueX
-mLx
+bbP
kwY
slY
slY
kwY
slY
slY
-jXE
+xyz
lTv
oem
oem
@@ -83837,7 +84025,7 @@ grn
lSI
lce
vKU
-pTr
+lPO
vfc
rtQ
rtQ
@@ -84021,10 +84209,10 @@ jCo
hff
jCo
slY
-wTn
-whS
+tIQ
+sEi
kPW
-tDm
+onI
jkS
lTN
mRD
@@ -84282,7 +84470,7 @@ slY
slY
slY
slY
-ciL
+bmL
lUz
ohj
ohj
@@ -84532,7 +84720,7 @@ sNz
hyO
roi
slY
-hFm
+arU
hAN
jMb
kzI
@@ -99229,7 +99417,7 @@ qtl
dDB
dDB
qIf
-uMl
+qxf
aQr
wCa
ulb
@@ -99743,7 +99931,7 @@ qtl
dDB
dDB
qIf
-tgJ
+wkZ
nQU
bDj
onP
@@ -103291,7 +103479,7 @@ xqC
gMK
dYo
oAC
-rZu
+knt
uPt
hyZ
hFO
@@ -103382,7 +103570,7 @@ gLb
bXH
vTY
nqV
-ruC
+wIG
wgL
oiA
kWs
@@ -104588,7 +104776,7 @@ xmO
sHe
nFW
mEy
-hsK
+ncf
nFA
kBH
onR
@@ -105091,14 +105279,14 @@ nyi
rvp
rvp
uIT
-xqC
+uIT
wSZ
tdI
hHE
nNi
hPs
xmO
-sJR
+ott
sIA
jPq
kaF
@@ -105344,18 +105532,18 @@ dDB
dDB
aJq
aJq
-jbm
-jbm
-jbm
-jbm
-jbm
-xmO
+pzd
+pzd
+pzd
+pzd
+pzd
+mHq
+mHq
+mHq
+mHq
xmO
xmO
-xmO
-xmO
-xmO
-jsn
+oTL
sIS
nFW
sRL
@@ -105601,17 +105789,17 @@ dDB
dDB
aJq
aJq
+pzd
+dYf
+xaj
+meP
+uWg
+sSl
+pSf
jbm
-jbm
-jbm
-jbm
-jbm
-jbm
-jbm
-jbm
-tbM
+pzd
iFi
-iQF
+jej
jej
jAs
nFW
@@ -105858,18 +106046,18 @@ dDB
aJq
aJq
aJq
-jbm
-vTO
-jbm
-jbm
-twN
-jbm
-jbm
+pzd
+vIN
+eyz
+mUC
+rIO
+rzR
+kZf
lqs
-xGS
-yfX
+pzd
+nFW
twN
-tDB
+nFW
nFW
nFW
tBL
@@ -106111,23 +106299,23 @@ dDB
dDB
dDB
dDB
-dDB
aJq
aJq
aJq
-jbm
-oEm
-jbm
-jbm
-oEm
-jbm
-twN
-nFW
+aJq
+pzd
+rDl
+ktN
+gEQ
+rIO
+jWR
+vmA
+rIO
rGL
puC
kZf
jey
-nFW
+pzd
hek
wXt
ndZ
@@ -106360,34 +106548,34 @@ aJq
aJq
aJq
aJq
+hwJ
+blb
+blb
+blb
+blb
+blb
+blb
+blb
+blb
+hwJ
aJq
aJq
-dDB
-dDB
-dDB
-dDB
-dDB
-dDB
-dDB
-aJq
-aJq
-aJq
-jbm
-twN
-ydt
-twN
-twN
-twN
-twN
-cgD
-twN
-jsn
-oTL
+pzd
+eKX
+jFc
+nRo
+tJN
+wCD
+kmb
+oDO
+rNK
+oDO
+oDO
jez
-nFW
-lPG
-wXt
-net
+dvs
+wYC
+pGX
+wYC
kDq
kDq
ldB
@@ -106445,7 +106633,7 @@ ntW
bgA
byq
pOX
-yaJ
+adl
kFY
aQm
qEz
@@ -106617,36 +106805,36 @@ aJq
aJq
aJq
aJq
-hwJ
-blb
-blb
-blb
-blb
-blb
-blb
-blb
-blb
-hwJ
aJq
-jbm
-jbm
-ydt
-jbm
-jbm
+dDB
+dDB
+dDB
+dDB
+dDB
+dDB
+dDB
+dDB
+tIE
+aJN
+doX
+aJN
ydt
-jbm
-skH
-lqs
-imd
-rIO
-pLK
+rGL
+rGL
+tRp
+rGL
+rGL
+rGL
+rGL
+xRX
+iux
jeX
-nFW
+pzd
qhq
tDq
rnn
udZ
-quf
+rtK
uct
lzR
wYC
@@ -106882,21 +107070,21 @@ dDB
dDB
dDB
dDB
-aJq
-aJq
-aJq
-jbm
+tIE
+tIE
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+tIE
+nFW
twN
-ydt
-jbm
-jbm
-kKN
-jbm
-jbm
-jbm
-jbm
-sJR
-jzl
nFW
nFW
nFW
@@ -107138,20 +107326,20 @@ dDB
dDB
dDB
dDB
-dDB
-aJq
-aJq
-aJq
-jbm
-oEm
-jbm
-jbm
-jbm
-ydt
-jbm
-jbm
-jbm
-jbm
+kmS
+dNi
+tIE
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+tIE
iHs
iQK
tDB
@@ -107395,22 +107583,22 @@ dDB
dDB
dDB
dDB
-dDB
-aJq
-aJq
-jbm
-jbm
-twN
-jbm
-jbm
-jbm
-twN
-twh
-ycz
-jbm
-jbm
-jbm
-iRv
+kmS
+dNi
+tIE
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+doX
+iHs
+pLK
bjX
nFW
nFW
@@ -107652,22 +107840,22 @@ dDB
dDB
dDB
dDB
-dDB
-aJq
-aJq
-jbm
-twN
-twN
-jbm
-jbm
-jbm
-puC
-ydt
-vra
-jbm
-nFW
-nFW
-iSB
+kmS
+dNi
+tIE
+bqy
+bqy
+cZm
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+doX
+pVo
+iRv
nFW
nFW
mjk
@@ -107909,22 +108097,22 @@ dDB
dDB
dDB
dDB
-dDB
-dDB
-aJq
-jbm
-pLk
-twN
-jbm
-jbm
-jbm
-ydt
-puC
-hJr
-jbm
-nFW
+tIE
+tIE
+tIE
+qBl
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+nMX
+doX
ivO
-pLK
+iRv
nFW
sJR
sJR
@@ -108166,22 +108354,22 @@ dDB
dDB
dDB
dDB
-dDB
-dDB
-aJq
-aJq
-jbm
-jbm
-jbm
-jbm
-jbm
-vMS
-puC
-jbm
-jbm
-nFW
+kmS
+dNi
+tIE
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+tIE
yju
-iRv
+pOL
jfP
nfc
jQF
@@ -108423,20 +108611,20 @@ dDB
dDB
dDB
dDB
-dDB
-dDB
-dDB
-aJq
-aJq
-aJq
-jbm
-jbm
-jbm
-jbm
-jbm
-jbm
-jbm
-nFW
+kmS
+dNi
+tIE
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+cZm
+bqy
+bqy
+tIE
kGz
kZo
nFW
@@ -108680,22 +108868,22 @@ dDB
dDB
dDB
dDB
-dDB
-dDB
-dDB
-aJq
-aJq
-aJq
-aJq
-aJq
-jbm
-jbm
-jbm
-jbm
-jbm
-jbm
-sJR
-njm
+kmS
+dNi
+tIE
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+doX
+yec
+fls
nFW
nFW
nFW
@@ -108938,22 +109126,22 @@ dDB
dDB
dDB
dDB
-dDB
-dDB
-dDB
-aJq
-aJq
-aJq
-aJq
-aJq
-jbm
-jbm
-jbm
-jbm
-nFW
-nFW
-iSO
-bHA
+tIE
+tIE
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+bqy
+tIE
+kGz
+jPr
+gxZ
dxz
sJR
xwy
@@ -109196,18 +109384,18 @@ dDB
dDB
dDB
dDB
-dDB
-dDB
-dDB
-aJq
-aJq
-aJq
-aJq
-aJq
-jbm
-jbm
-jbm
-jbm
+tIE
+aJN
+aJN
+aJN
+uJZ
+aJN
+doX
+doX
+aJN
+aJN
+aJN
+tIE
nFW
iSW
njm
@@ -109462,9 +109650,9 @@ hwJ
aJq
aJq
vcE
-vcE
-vcE
-vcE
+jIb
+pyt
+nvS
nFW
iUy
vtL
@@ -110488,8 +110676,8 @@ aJq
aJq
aJq
aJq
-aJq
-weg
+iMy
+jJy
nvS
kbY
imE
@@ -110744,8 +110932,8 @@ aJq
aJq
aJq
aJq
-aJq
-aJq
+iMy
+iMy
weg
jKf
nvS
@@ -110999,9 +111187,9 @@ dDB
dDB
aJq
aJq
-aJq
-aJq
-aJq
+iMy
+iMy
+iMy
aJq
weg
weg
@@ -111256,8 +111444,8 @@ dDB
dDB
aJq
aJq
-aJq
-aJq
+iMy
+kOW
aJq
aJq
weg
@@ -111513,7 +111701,7 @@ dDB
dDB
aJq
aJq
-aJq
+ejV
aJq
aJq
aJq
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index 15c9aae2b71..41f0a245642 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -1692,6 +1692,14 @@
},
/turf/open/floor/iron/white,
/area/station/medical/chemistry)
+"atk" = (
+/obj/item/kirbyplants/random,
+/obj/structure/sign/poster/official/random/directional/west,
+/obj/effect/turf_decal/tile/purple/half/contrasted{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"atl" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/components/binary/valve/digital{
@@ -3029,6 +3037,12 @@
/obj/structure/sign/warning/electric_shock/directional/west,
/turf/open/space/basic,
/area/space)
+"aLg" = (
+/obj/structure/filingcabinet/chestdrawer,
+/obj/effect/turf_decal/delivery,
+/obj/machinery/airalarm/directional/south,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"aLv" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -3413,19 +3427,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/science/robotics/lab)
-"aPD" = (
-/obj/structure/disposalpipe/segment,
-/obj/machinery/door/airlock/mining{
- name = "Mining Dock"
- },
-/obj/effect/turf_decal/stripes/line,
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/obj/machinery/door/firedoor,
-/obj/effect/mapping_helpers/airlock/access/all/supply/mining,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"aPO" = (
/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible,
/obj/effect/turf_decal/tile/yellow{
@@ -3566,6 +3567,16 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/station/security/courtroom)
+"aSj" = (
+/obj/structure/disposalpipe/trunk{
+ dir = 1
+ },
+/obj/machinery/disposal/bin,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/delivery,
+/obj/structure/sign/poster/official/random/directional/south,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"aSl" = (
/obj/machinery/door/firedoor,
/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
@@ -3807,6 +3818,16 @@
/obj/effect/turf_decal/tile/yellow/opposingcorners,
/turf/open/floor/iron,
/area/station/engineering/supermatter/room)
+"aWe" = (
+/obj/structure/table/reinforced,
+/obj/effect/decal/cleanable/dirt,
+/obj/item/flashlight/lamp,
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/purple/half/contrasted{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"aWk" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -4983,17 +5004,6 @@
},
/turf/open/floor/iron/grimy,
/area/station/command/heads_quarters/hos)
-"bkr" = (
-/obj/structure/disposalpipe/segment{
- dir = 6
- },
-/obj/effect/decal/cleanable/dirt,
-/obj/machinery/conveyor{
- id = "cargodisposals"
- },
-/obj/effect/mapping_helpers/burnt_floor,
-/turf/open/floor/plating,
-/area/station/cargo/sorting)
"bkD" = (
/obj/structure/cable,
/obj/effect/decal/cleanable/dirt,
@@ -7297,16 +7307,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/plating,
/area/station/maintenance/department/science)
-"bLN" = (
-/obj/structure/disposalpipe/trunk{
- dir = 1
- },
-/obj/machinery/disposal/bin,
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/delivery,
-/obj/structure/sign/poster/official/random/directional/south,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"bLP" = (
/obj/machinery/camera/directional/east{
c_tag = "Permabrig - Kitchen Entrance";
@@ -7420,6 +7420,16 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron,
/area/station/science/robotics/mechbay)
+"bNi" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/disposalpipe/segment,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/delivery,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"bNr" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/turf_decal/tile/neutral/fourcorners,
@@ -9981,6 +9991,22 @@
/obj/machinery/status_display/evac/directional/north,
/turf/open/floor/iron,
/area/station/ai_monitored/command/storage/eva)
+"ctR" = (
+/obj/structure/table,
+/obj/effect/decal/cleanable/dirt,
+/obj/item/clipboard,
+/obj/item/toy/figure/miner,
+/obj/machinery/light/directional/north,
+/obj/machinery/light_switch/directional/west{
+ pixel_x = -42
+ },
+/obj/effect/turf_decal/bot,
+/obj/machinery/firealarm/directional/west,
+/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"ctU" = (
/obj/structure/chair/office{
dir = 1
@@ -10140,22 +10166,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/command/heads_quarters/hop)
-"cwd" = (
-/obj/structure/rack,
-/obj/effect/decal/cleanable/dirt,
-/obj/item/storage/toolbox/emergency{
- pixel_x = -3;
- pixel_y = 3
- },
-/obj/item/storage/toolbox/emergency,
-/obj/item/shovel,
-/obj/item/shovel,
-/obj/item/pickaxe,
-/obj/item/pickaxe,
-/obj/effect/turf_decal/bot,
-/obj/machinery/light/small/directional/south,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"cwe" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
@@ -10207,12 +10217,6 @@
/obj/structure/sign/warning/radiation/directional/south,
/turf/open/floor/iron,
/area/station/engineering/supermatter/room)
-"cwK" = (
-/obj/effect/decal/cleanable/cobweb/cobweb2,
-/obj/effect/decal/cleanable/dirt,
-/obj/structure/reagent_dispensers/watertank,
-/turf/open/floor/plating,
-/area/station/maintenance/starboard/fore)
"cwV" = (
/obj/effect/landmark/start/hangover,
/obj/structure/disposalpipe/segment{
@@ -10322,14 +10326,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron,
/area/station/medical/treatment_center)
-"cyc" = (
-/obj/structure/cable,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/effect/turf_decal/tile/purple/half/contrasted,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"cyq" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -10405,6 +10401,13 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron,
/area/station/engineering/atmos)
+"cze" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"czf" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/wood/large,
@@ -11084,9 +11087,6 @@
/obj/item/radio/intercom/directional/north,
/turf/open/floor/iron/grimy,
/area/station/tcommsat/computer)
-"cGV" = (
-/turf/closed/wall,
-/area/station/cargo/miningoffice)
"cHb" = (
/obj/machinery/door/firedoor/heavy,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -11803,6 +11803,10 @@
},
/turf/open/floor/iron/large,
/area/station/science/xenobiology)
+"cQO" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"cQT" = (
/obj/structure/table/reinforced,
/obj/machinery/computer/security/telescreen{
@@ -12685,6 +12689,12 @@
},
/turf/open/floor/plating,
/area/station/maintenance/department/medical/morgue)
+"dcA" = (
+/obj/effect/decal/cleanable/cobweb/cobweb2,
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/reagent_dispensers/watertank,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/fore)
"dcG" = (
/obj/effect/turf_decal/trimline/red/filled/line,
/obj/effect/landmark/start/depsec/science,
@@ -13088,6 +13098,10 @@
/obj/effect/turf_decal/siding/wood/corner,
/turf/open/floor/iron/dark,
/area/station/hallway/secondary/service)
+"dih" = (
+/obj/effect/decal/cleanable/oil,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"din" = (
/obj/structure/table/wood,
/obj/item/paper_bin,
@@ -13701,6 +13715,19 @@
},
/turf/open/floor/iron,
/area/station/maintenance/department/chapel)
+"dri" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/maintenance/starboard/fore)
"drj" = (
/obj/structure/cable,
/obj/effect/turf_decal/tile/neutral/fourcorners,
@@ -13819,6 +13846,15 @@
/obj/machinery/rnd/server,
/turf/open/floor/circuit/green/telecomms/mainframe,
/area/station/science/server)
+"dsq" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/brown{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"dsy" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -13936,6 +13972,13 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/security/detectives_office/private_investigators_office)
+"dtp" = (
+/obj/structure/disposalpipe/segment{
+ dir = 9
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"dtJ" = (
/obj/machinery/power/apc/auto_name/directional/north,
/obj/structure/cable,
@@ -14005,13 +14048,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/science/xenobiology)
-"dux" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/landmark/start/shaft_miner,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"duA" = (
/turf/closed/wall/r_wall,
/area/station/command/corporate_showroom)
@@ -15034,6 +15070,13 @@
},
/turf/open/floor/iron/white,
/area/station/medical/cryo)
+"dIz" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"dIE" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -15667,17 +15710,6 @@
},
/turf/open/floor/plating,
/area/station/engineering/supermatter/room)
-"dPC" = (
-/obj/structure/table,
-/obj/machinery/microwave{
- desc = "Cooks and boils stuff, somehow.";
- pixel_x = -3;
- pixel_y = 5
- },
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/bot,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"dPD" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -15797,6 +15829,13 @@
dir = 8
},
/area/station/hallway/primary/fore)
+"dRf" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"dRh" = (
/obj/machinery/telecomms/bus/preset_four,
/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
@@ -16222,16 +16261,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron,
/area/station/maintenance/port)
-"dXs" = (
-/obj/structure/table/reinforced,
-/obj/effect/decal/cleanable/dirt,
-/obj/item/flashlight/lamp,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/purple/half/contrasted{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"dXw" = (
/obj/structure/sign/painting/large/library_private{
dir = 1;
@@ -17167,6 +17196,26 @@
},
/turf/open/floor/iron/dark/textured_large,
/area/station/engineering/atmos/hfr_room)
+"eld" = (
+/obj/structure/cable,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/requests_console/directional/south{
+ department = "Mining";
+ name = "Mining Requests Console"
+ },
+/obj/machinery/requests_console/directional/south{
+ department = "Mining";
+ name = "Mining Requests Console"
+ },
+/obj/machinery/camera/directional/south{
+ c_tag = "Cargo - Mining Dock";
+ name = "cargo camera"
+ },
+/obj/effect/turf_decal/tile/brown/half/contrasted,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"eln" = (
/obj/effect/turf_decal/stripes/end{
dir = 4
@@ -17229,13 +17278,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/command/gateway)
-"elO" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/tile/brown/half/contrasted{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/maintenance/starboard/fore)
"elP" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/turf_decal/tile/yellow/fourcorners,
@@ -18718,11 +18760,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/secondary/entry)
-"eFU" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/structure/cable,
-/turf/open/floor/plating,
-/area/station/maintenance/starboard/fore)
"eGb" = (
/obj/effect/spawner/random/trash/mess,
/turf/open/floor/wood,
@@ -18993,6 +19030,14 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden,
/turf/open/floor/plating,
/area/station/maintenance/department/science/xenobiology)
+"eIA" = (
+/obj/structure/disposalpipe/segment,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/purple/half/contrasted{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"eIQ" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -19154,6 +19199,11 @@
/obj/item/radio/intercom/directional/south,
/turf/open/floor/iron,
/area/station/engineering/supermatter/room)
+"eKS" = (
+/obj/machinery/rnd/bepis,
+/obj/effect/turf_decal/box/white,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"eKU" = (
/obj/effect/turf_decal/tile/red/anticorner/contrasted{
dir = 1
@@ -20289,10 +20339,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/security/range)
-"eYt" = (
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"eYy" = (
/obj/structure/cable,
/obj/structure/closet/secure_closet/atmospherics,
@@ -20482,13 +20528,6 @@
/obj/effect/decal/cleanable/cobweb,
/turf/open/floor/iron/smooth,
/area/station/maintenance/department/science/xenobiology)
-"fbu" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"fbA" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -21528,6 +21567,23 @@
/obj/structure/chair/office,
/turf/open/floor/iron/grimy,
/area/station/tcommsat/computer)
+"fnN" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/structure/disposalpipe/segment,
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/door/airlock/mining{
+ name = "Mining Dock"
+ },
+/obj/effect/turf_decal/stripes/line,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/machinery/door/firedoor,
+/obj/effect/mapping_helpers/airlock/access/all/supply/mining,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"foh" = (
/obj/machinery/atmospherics/components/binary/volume_pump{
name = "Ports to Distro"
@@ -21781,6 +21837,19 @@
},
/turf/open/floor/iron,
/area/station/commons/locker)
+"fsg" = (
+/obj/structure/disposalpipe/segment,
+/obj/machinery/door/airlock/mining{
+ name = "Mining Dock"
+ },
+/obj/effect/turf_decal/stripes/line,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/machinery/door/firedoor,
+/obj/effect/mapping_helpers/airlock/access/all/supply/mining,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"fsl" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment,
@@ -21962,14 +22031,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/grimy,
/area/station/service/library)
-"ftS" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/brown/half/contrasted{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"ftU" = (
/obj/structure/cable,
/obj/effect/turf_decal/siding/yellow,
@@ -22145,6 +22206,11 @@
/obj/machinery/light/small/directional/north,
/turf/open/floor/iron/dark,
/area/station/science/xenobiology)
+"fwD" = (
+/obj/structure/table,
+/obj/effect/turf_decal/bot,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"fwK" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -22406,14 +22472,6 @@
/obj/effect/turf_decal/delivery,
/turf/open/floor/iron,
/area/station/engineering/storage)
-"fAj" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/cable,
-/obj/structure/disposalpipe/segment,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"fAn" = (
/obj/machinery/holopad,
/obj/effect/turf_decal/bot,
@@ -22566,6 +22624,12 @@
/obj/machinery/light/small/directional/south,
/turf/open/floor/iron/dark,
/area/station/hallway/secondary/entry)
+"fCb" = (
+/obj/effect/turf_decal/loading_area{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"fCf" = (
/obj/machinery/door/poddoor/preopen{
id = "atmoslock";
@@ -23090,6 +23154,11 @@
},
/turf/open/floor/iron/large,
/area/station/security/checkpoint/escape)
+"fJm" = (
+/obj/effect/landmark/start/shaft_miner,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"fJq" = (
/turf/closed/wall,
/area/station/security/brig)
@@ -23863,6 +23932,13 @@
/obj/effect/spawner/random/maintenance,
/turf/open/floor/iron/grimy,
/area/station/service/abandoned_gambling_den)
+"fUl" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/conveyor{
+ id = "cargodisposals"
+ },
+/turf/open/floor/plating,
+/area/station/cargo/sorting)
"fUq" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/stripes/line{
@@ -23886,12 +23962,6 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/commons/fitness/recreation)
-"fUr" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell{
- dir = 8
- },
-/turf/open/floor/iron/dark/textured_large,
-/area/station/medical/cryo)
"fUF" = (
/obj/structure/table/reinforced,
/obj/structure/window/reinforced/spawner/directional/east,
@@ -24333,6 +24403,14 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/engineering/atmos/project)
+"fZz" = (
+/obj/effect/landmark/start/shaft_miner,
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"fZG" = (
/obj/effect/turf_decal/stripes/corner,
/obj/effect/turf_decal/stripes/corner{
@@ -24578,11 +24656,6 @@
},
/turf/open/floor/iron,
/area/station/service/hydroponics)
-"gco" = (
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/brown/half/contrasted,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"gcr" = (
/obj/effect/turf_decal/tile/neutral/half/contrasted,
/turf/open/floor/iron,
@@ -24717,6 +24790,11 @@
/obj/machinery/light/small/dim/directional/north,
/turf/open/floor/plating,
/area/station/maintenance/department/security)
+"gdD" = (
+/obj/structure/closet/secure_closet/miner,
+/obj/effect/turf_decal/delivery,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"gdE" = (
/obj/structure/chair/office,
/obj/effect/turf_decal/tile/neutral/fourcorners,
@@ -25941,6 +26019,11 @@
},
/turf/open/floor/iron/dark/corner,
/area/station/engineering/atmos/pumproom)
+"grT" = (
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/brown/half/contrasted,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"grV" = (
/obj/effect/turf_decal/arrows/red{
dir = 4;
@@ -26123,11 +26206,6 @@
},
/turf/open/floor/iron,
/area/station/commons/storage/primary)
-"guj" = (
-/obj/effect/landmark/start/shaft_miner,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"gum" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -26916,6 +26994,9 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron/cafeteria,
/area/station/security/prison/mess)
+"gDE" = (
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"gDP" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -27167,6 +27248,12 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/aisat/exterior)
+"gGM" = (
+/obj/effect/turf_decal/tile/purple/half/contrasted{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"gGT" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/toilet{
@@ -28159,6 +28246,13 @@
},
/turf/open/floor/iron,
/area/station/service/abandoned_gambling_den/gaming)
+"gUe" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/maintenance/starboard/fore)
"gUi" = (
/obj/effect/turf_decal/stripes/red/line{
dir = 10
@@ -29335,12 +29429,6 @@
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron/white/smooth_large,
/area/station/medical/medbay)
-"hkn" = (
-/obj/structure/filingcabinet/chestdrawer,
-/obj/effect/turf_decal/delivery,
-/obj/machinery/airalarm/directional/south,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"hkt" = (
/obj/effect/spawner/random/engineering/tank,
/turf/open/floor/plating,
@@ -30357,13 +30445,6 @@
},
/turf/open/floor/glass/reinforced,
/area/station/maintenance/department/science/xenobiology)
-"hzs" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
- dir = 8
- },
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"hzx" = (
/obj/machinery/firealarm/directional/west,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -32924,6 +33005,16 @@
/obj/item/stack/rods/fifty,
/turf/open/floor/plating,
/area/station/maintenance/department/eva/abandoned)
+"ihc" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/disposalpipe/segment{
+ dir = 6
+ },
+/obj/effect/turf_decal/tile/brown/half/contrasted,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"iho" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -32985,13 +33076,6 @@
},
/turf/open/floor/plating,
/area/station/medical/virology)
-"iio" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/tile/brown/half/contrasted{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"iiy" = (
/obj/structure/easel,
/turf/open/floor/iron,
@@ -34242,16 +34326,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/hallway/secondary/entry)
-"izj" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/cable,
-/obj/structure/disposalpipe/segment,
-/obj/effect/turf_decal/tile/purple{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"izo" = (
/obj/structure/table/wood,
/obj/item/gavelblock,
@@ -35944,6 +36018,13 @@
/obj/effect/turf_decal/tile/neutral,
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
+"iWJ" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/loading_area{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"iWR" = (
/obj/effect/turf_decal/tile/brown/half/contrasted{
dir = 8
@@ -35978,14 +36059,6 @@
},
/turf/open/floor/iron,
/area/station/engineering/lobby)
-"iXd" = (
-/obj/effect/landmark/start/shaft_miner,
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 8
- },
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"iXj" = (
/obj/effect/landmark/start/hangover,
/obj/effect/turf_decal/bot,
@@ -36808,11 +36881,6 @@
/obj/structure/sign/warning/secure_area/directional/west,
/turf/open/floor/plating,
/area/station/engineering/atmos/mix)
-"jfO" = (
-/obj/structure/table,
-/obj/effect/turf_decal/bot,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"jfP" = (
/obj/structure/disposalpipe/segment,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -37113,6 +37181,21 @@
dir = 8
},
/area/station/hallway/primary/port)
+"jjK" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/disposalpipe/segment{
+ dir = 6
+ },
+/obj/structure/sign/nanotrasen{
+ pixel_y = 32
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/hallway/primary/central/fore)
"jjU" = (
/obj/effect/turf_decal/tile/neutral/half/contrasted,
/turf/open/floor/iron,
@@ -37970,6 +38053,19 @@
"jtC" = (
/turf/open/floor/plating,
/area/station/service/abandoned_gambling_den)
+"jtE" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/disposalpipe/segment{
+ dir = 9
+ },
+/obj/machinery/firealarm/directional/east,
+/obj/effect/turf_decal/tile/neutral{
+ dir = 4
+ },
+/obj/machinery/light/small/directional/east,
+/turf/open/floor/iron,
+/area/station/hallway/primary/central/fore)
"jtV" = (
/obj/structure/sign/warning/electric_shock,
/turf/closed/wall/r_wall,
@@ -38518,13 +38614,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/science/lobby)
-"jBM" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"jCb" = (
/obj/machinery/computer/records/security{
dir = 8
@@ -38608,13 +38697,6 @@
/obj/item/pen,
/turf/open/floor/wood,
/area/station/service/library/abandoned)
-"jCu" = (
-/obj/machinery/computer/order_console/mining,
-/obj/effect/decal/cleanable/dirt,
-/obj/machinery/light/directional/north,
-/obj/effect/turf_decal/bot,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"jCv" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/hydroponics/constructable,
@@ -38657,6 +38739,17 @@
/obj/effect/mapping_helpers/airlock/access/all/service/lawyer,
/turf/open/floor/iron,
/area/station/service/lawoffice)
+"jCR" = (
+/obj/structure/disposalpipe/segment{
+ dir = 6
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/conveyor{
+ id = "cargodisposals"
+ },
+/obj/effect/mapping_helpers/burnt_floor,
+/turf/open/floor/plating,
+/area/station/cargo/sorting)
"jCS" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -39262,14 +39355,6 @@
/obj/effect/turf_decal/tile/blue/opposingcorners,
/turf/open/floor/iron/white,
/area/station/command/heads_quarters/cmo)
-"jKY" = (
-/obj/structure/cable,
-/obj/effect/turf_decal/bot,
-/obj/structure/table,
-/obj/item/storage/medkit/regular,
-/obj/machinery/power/apc/auto_name/directional/west,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"jLa" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/railing{
@@ -39852,11 +39937,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/white,
/area/station/medical/medbay)
-"jRc" = (
-/obj/machinery/power/apc/auto_name/directional/north,
-/obj/structure/cable,
-/turf/open/floor/plating,
-/area/station/maintenance/starboard/fore)
"jRg" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
@@ -40091,6 +40171,23 @@
"jUx" = (
/turf/open/floor/plating,
/area/station/maintenance/department/science)
+"jUy" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/structure/disposalpipe/segment,
+/obj/machinery/door/firedoor,
+/obj/effect/turf_decal/stripes/line,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/machinery/door/airlock/mining/glass{
+ name = "Delivery Office"
+ },
+/obj/effect/mapping_helpers/airlock/access/any/supply/shipping,
+/obj/effect/mapping_helpers/airlock/access/any/supply/mining,
+/turf/open/floor/iron,
+/area/station/cargo/sorting)
"jUC" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -41946,6 +42043,11 @@
"ksK" = (
/turf/closed/wall/r_wall,
/area/station/command/gateway)
+"ksL" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"ksP" = (
/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible{
dir = 4
@@ -42423,6 +42525,13 @@
/obj/effect/turf_decal/tile/neutral/full,
/turf/open/floor/iron/large,
/area/station/ai_monitored/command/storage/eva)
+"kzi" = (
+/obj/structure/closet/secure_closet/miner,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/delivery,
+/obj/machinery/status_display/evac/directional/north,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"kzm" = (
/obj/structure/disposalpipe/sorting/mail/flip{
dir = 4;
@@ -43152,12 +43261,6 @@
/obj/structure/sign/warning/pods,
/turf/closed/wall,
/area/station/hallway/secondary/entry)
-"kKx" = (
-/obj/effect/turf_decal/loading_area{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"kKy" = (
/obj/machinery/airalarm/directional/east,
/obj/machinery/rnd/production/techfab/department/medical,
@@ -43784,11 +43887,6 @@
/obj/effect/turf_decal/delivery,
/turf/open/floor/iron/dark,
/area/station/engineering/main)
-"kTs" = (
-/obj/structure/closet/secure_closet/miner,
-/obj/effect/turf_decal/delivery,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"kTy" = (
/obj/structure/chair/office{
dir = 8
@@ -45088,13 +45186,6 @@
/obj/effect/mapping_helpers/airlock/access/all/engineering/general,
/turf/open/floor/iron,
/area/station/maintenance/solars/starboard/fore)
-"ljQ" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/loading_area{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"ljS" = (
/obj/structure/cable,
/obj/effect/spawner/structure/window/reinforced,
@@ -45234,13 +45325,6 @@
/obj/machinery/light/directional/west,
/turf/open/floor/iron,
/area/station/hallway/primary/starboard)
-"llj" = (
-/obj/structure/disposalpipe/segment{
- dir = 9
- },
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"llm" = (
/obj/structure/chair/office/tactical{
dir = 8
@@ -45818,6 +45902,16 @@
/obj/effect/turf_decal/tile/blue/fourcorners,
/turf/open/floor/iron,
/area/station/medical/treatment_center)
+"ltB" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/structure/disposalpipe/segment,
+/obj/effect/turf_decal/tile/purple{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"ltD" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/smart/simple/yellow/visible,
@@ -46489,6 +46583,22 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/station/engineering/storage)
+"lBB" = (
+/obj/structure/rack,
+/obj/effect/decal/cleanable/dirt,
+/obj/item/storage/toolbox/emergency{
+ pixel_x = -3;
+ pixel_y = 3
+ },
+/obj/item/storage/toolbox/emergency,
+/obj/item/shovel,
+/obj/item/shovel,
+/obj/item/pickaxe,
+/obj/item/pickaxe,
+/obj/effect/turf_decal/bot,
+/obj/machinery/light/small/directional/south,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"lBG" = (
/obj/structure/cable,
/obj/effect/spawner/structure/window/reinforced,
@@ -48503,6 +48613,16 @@
/obj/effect/landmark/start/hangover,
/turf/open/floor/carpet/orange,
/area/station/commons/dorms)
+"mcK" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/structure/disposalpipe/segment,
+/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"mcV" = (
/obj/machinery/door/airlock/engineering/glass{
name = "Supermatter Engine Room"
@@ -49104,14 +49224,6 @@
"mlE" = (
/turf/closed/wall/r_wall,
/area/station/ai_monitored/command/storage/eva)
-"mlF" = (
-/obj/item/kirbyplants/random,
-/obj/structure/sign/poster/official/random/directional/west,
-/obj/effect/turf_decal/tile/purple/half/contrasted{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"mlM" = (
/obj/structure/table/wood,
/obj/machinery/computer/records/medical/laptop,
@@ -49658,13 +49770,6 @@
/obj/effect/turf_decal/tile/yellow/fourcorners,
/turf/open/floor/iron,
/area/station/engineering/storage)
-"mtL" = (
-/obj/structure/closet/secure_closet/miner,
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/delivery,
-/obj/machinery/status_display/evac/directional/north,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"mtO" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/turf_decal/tile/yellow{
@@ -50418,10 +50523,6 @@
/obj/structure/cable,
/turf/open/floor/engine,
/area/station/maintenance/disposal/incinerator)
-"mDm" = (
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"mDo" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -52654,11 +52755,6 @@
/obj/effect/spawner/random/trash/hobo_squat,
/turf/open/floor/plating,
/area/station/maintenance/department/chapel)
-"nhj" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"nhm" = (
/turf/closed/wall/r_wall,
/area/station/maintenance/starboard/lesser)
@@ -53185,6 +53281,11 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/security/courtroom)
+"nos" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/fore)
"not" = (
/obj/effect/turf_decal/stripes/line{
dir = 10
@@ -53397,6 +53498,11 @@
},
/turf/open/floor/iron,
/area/station/security/warden)
+"nro" = (
+/obj/machinery/power/apc/auto_name/directional/north,
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/fore)
"nry" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/dirt,
@@ -53477,6 +53583,16 @@
},
/turf/open/floor/iron/dark,
/area/station/maintenance/port)
+"nsI" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/disposalpipe/segment{
+ dir = 9
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"nsV" = (
/obj/structure/table/reinforced,
/obj/structure/reagent_dispensers/wall/peppertank/directional/west,
@@ -54379,12 +54495,6 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/iron,
/area/station/maintenance/port)
-"nEE" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"nEJ" = (
/obj/structure/cable,
/obj/effect/turf_decal/trimline/yellow/line,
@@ -55494,6 +55604,12 @@
/obj/item/storage/medkit/regular,
/turf/open/floor/iron,
/area/station/commons/fitness/recreation)
+"nTw" = (
+/obj/structure/cable,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/purple/half/contrasted,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"nTz" = (
/obj/item/stack/sheet/plasteel/twenty,
/obj/item/stack/sheet/rglass{
@@ -55703,6 +55819,22 @@
/obj/effect/turf_decal/tile/red/fourcorners,
/turf/open/floor/iron/dark,
/area/station/security/lockers)
+"nXf" = (
+/obj/machinery/door/firedoor,
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/door/airlock/mining/glass{
+ name = "Delivery Office"
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/obj/effect/mapping_helpers/airlock/access/any/supply/mining,
+/obj/effect/mapping_helpers/airlock/access/any/supply/shipping,
+/turf/open/floor/iron,
+/area/station/cargo/sorting)
"nXj" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -56241,6 +56373,14 @@
/obj/structure/closet,
/turf/open/floor/plating,
/area/station/maintenance/fore)
+"oea" = (
+/obj/structure/closet/wardrobe/miner,
+/obj/effect/decal/cleanable/dirt,
+/obj/item/storage/backpack/satchel/explorer,
+/obj/effect/turf_decal/bot,
+/obj/item/radio/intercom/directional/south,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"oec" = (
/obj/effect/spawner/structure/window/reinforced/tinted,
/turf/open/floor/plating/airless,
@@ -56360,6 +56500,12 @@
},
/turf/open/floor/iron,
/area/station/engineering/atmos/mix)
+"ofM" = (
+/obj/effect/turf_decal/tile/purple/half/contrasted{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"ofN" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/conveyor{
@@ -56511,6 +56657,14 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
+"ohR" = (
+/obj/structure/cable,
+/obj/structure/extinguisher_cabinet/directional/west,
+/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"ohZ" = (
/obj/structure/rack,
/obj/effect/spawner/random/techstorage/service_all,
@@ -56751,13 +56905,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/station/security/prison/garden)
-"okN" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"okV" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/reagent_dispensers/plumbed{
@@ -56911,6 +57058,10 @@
},
/turf/open/floor/iron,
/area/station/cargo/storage)
+"oml" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"omv" = (
/obj/structure/table,
/obj/item/flashlight/lamp,
@@ -57617,14 +57768,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/station/maintenance/port)
-"owZ" = (
-/obj/structure/cable,
-/obj/structure/disposalpipe/segment{
- dir = 10
- },
-/obj/effect/turf_decal/tile/purple/half/contrasted,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"oxb" = (
/obj/machinery/duct,
/obj/effect/turf_decal/siding/white,
@@ -57868,16 +58011,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/grimy,
/area/station/command/heads_quarters/captain/private)
-"oAV" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/disposalpipe/segment{
- dir = 6
- },
-/obj/effect/turf_decal/tile/brown/half/contrasted,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"oAW" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -59429,6 +59562,9 @@
/obj/machinery/newscaster/directional/east,
/turf/open/floor/wood,
/area/station/hallway/secondary/service)
+"oWV" = (
+/turf/closed/wall,
+/area/station/cargo/miningoffice)
"oXi" = (
/obj/effect/turf_decal/bot_white/left,
/obj/effect/turf_decal/tile/neutral{
@@ -61441,9 +61577,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/hallway/secondary/exit/departure_lounge)
-"pxS" = (
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"pxT" = (
/obj/effect/spawner/random/structure/crate,
/turf/open/floor/plating,
@@ -61909,13 +62042,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/security/armory)
-"pDy" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell{
- dir = 8
- },
-/obj/machinery/status_display/ai/directional/south,
-/turf/open/floor/iron/dark/textured_large,
-/area/station/medical/cryo)
"pDE" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -63510,16 +63636,6 @@
},
/turf/open/floor/iron/dark/corner,
/area/station/engineering/atmos/pumproom)
-"pUs" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/disposalpipe/segment{
- dir = 9
- },
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"pUw" = (
/obj/machinery/holopad,
/obj/effect/turf_decal/bot,
@@ -64739,22 +64855,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/command/bridge)
-"qko" = (
-/obj/structure/table,
-/obj/effect/decal/cleanable/dirt,
-/obj/item/clipboard,
-/obj/item/toy/figure/miner,
-/obj/machinery/light/directional/north,
-/obj/machinery/light_switch/directional/west{
- pixel_x = -42
- },
-/obj/effect/turf_decal/bot,
-/obj/machinery/firealarm/directional/west,
-/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"qkv" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -64911,19 +65011,6 @@
},
/turf/open/floor/plating,
/area/station/engineering/supermatter/room)
-"qmT" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/tile/brown/half/contrasted{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/maintenance/starboard/fore)
"qnc" = (
/obj/machinery/firealarm/directional/south,
/obj/effect/turf_decal/tile/blue{
@@ -65351,14 +65438,6 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/science/xenobiology)
-"qsF" = (
-/obj/structure/cable,
-/obj/structure/extinguisher_cabinet/directional/west,
-/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"qsN" = (
/obj/structure/chair{
dir = 4
@@ -65786,6 +65865,13 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/security/execution/transfer)
+"qyO" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"qyX" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -68277,15 +68363,6 @@
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron/white,
/area/station/medical/medbay/lobby)
-"rgC" = (
-/obj/structure/cable,
-/obj/structure/table/reinforced,
-/obj/effect/decal/cleanable/dirt,
-/obj/item/folder/yellow,
-/obj/item/gps/mining,
-/obj/effect/turf_decal/tile/brown/anticorner/contrasted,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"rgG" = (
/obj/structure/closet/secure_closet/engineering_personal,
/obj/effect/decal/cleanable/dirt,
@@ -68918,23 +68995,6 @@
/obj/machinery/light/dim/directional/east,
/turf/open/floor/iron/dark,
/area/station/tcommsat/computer)
-"rmH" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/cable,
-/obj/structure/disposalpipe/segment,
-/obj/effect/decal/cleanable/dirt,
-/obj/machinery/door/airlock/mining{
- name = "Mining Dock"
- },
-/obj/effect/turf_decal/stripes/line,
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/obj/machinery/door/firedoor,
-/obj/effect/mapping_helpers/airlock/access/all/supply/mining,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"rmI" = (
/obj/structure/table/reinforced,
/obj/item/electronics/apc,
@@ -69913,13 +69973,6 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/iron,
/area/station/cargo/storage)
-"rAl" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/machinery/conveyor{
- id = "cargodisposals"
- },
-/turf/open/floor/plating,
-/area/station/cargo/sorting)
"rAm" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/turf_decal/tile/yellow/half/contrasted{
@@ -70624,6 +70677,15 @@
/obj/machinery/atmospherics/pipe/smart/simple/yellow/visible,
/turf/open/floor/plating,
/area/station/engineering/atmos/mix)
+"rKu" = (
+/obj/structure/cable,
+/obj/structure/table/reinforced,
+/obj/effect/decal/cleanable/dirt,
+/obj/item/folder/yellow,
+/obj/item/gps/mining,
+/obj/effect/turf_decal/tile/brown/anticorner/contrasted,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"rKA" = (
/obj/machinery/firealarm/directional/east,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -71218,14 +71280,6 @@
/obj/structure/mirror/directional/west,
/turf/open/floor/wood,
/area/station/maintenance/port/aft)
-"rQF" = (
-/obj/structure/closet/wardrobe/miner,
-/obj/effect/decal/cleanable/dirt,
-/obj/item/storage/backpack/satchel/explorer,
-/obj/effect/turf_decal/bot,
-/obj/item/radio/intercom/directional/south,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"rQI" = (
/obj/machinery/airlock_sensor/incinerator_atmos{
pixel_x = 24
@@ -72524,11 +72578,6 @@
},
/turf/open/space/basic,
/area/space)
-"sgK" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/landmark/event_spawn,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"sgZ" = (
/obj/structure/disposalpipe/segment,
/obj/structure/cable,
@@ -73006,6 +73055,13 @@
},
/turf/open/floor/iron/white,
/area/station/science/research)
+"snh" = (
+/obj/machinery/computer/order_console/mining,
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/light/directional/north,
+/obj/effect/turf_decal/bot,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"snj" = (
/obj/effect/turf_decal/stripes/line,
/obj/effect/decal/cleanable/dirt,
@@ -73406,14 +73462,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron,
/area/station/medical/pharmacy)
-"stf" = (
-/obj/structure/disposalpipe/segment,
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/tile/purple/half/contrasted{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"stp" = (
/obj/machinery/airalarm/directional/west,
/obj/effect/turf_decal/trimline/brown/filled/line{
@@ -73792,6 +73840,14 @@
/obj/item/papercutter,
/turf/open/floor/iron/grimy,
/area/station/command/bridge)
+"sxu" = (
+/obj/structure/cable,
+/obj/structure/disposalpipe/segment{
+ dir = 10
+ },
+/obj/effect/turf_decal/tile/purple/half/contrasted,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"sxD" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -74222,22 +74278,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/half,
/area/station/service/hydroponics)
-"sCW" = (
-/obj/machinery/door/firedoor,
-/obj/effect/decal/cleanable/dirt,
-/obj/machinery/door/airlock/mining/glass{
- name = "Delivery Office"
- },
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/obj/effect/turf_decal/stripes/line{
- dir = 4
- },
-/obj/effect/mapping_helpers/airlock/access/any/supply/mining,
-/obj/effect/mapping_helpers/airlock/access/any/supply/shipping,
-/turf/open/floor/iron,
-/area/station/cargo/sorting)
"sCY" = (
/obj/structure/cable,
/obj/machinery/power/tracker,
@@ -74921,11 +74961,6 @@
/obj/structure/sign/poster/official/build/directional/north,
/turf/open/floor/iron,
/area/station/science/robotics/mechbay)
-"sLg" = (
-/obj/machinery/rnd/bepis,
-/obj/effect/turf_decal/box/white,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"sLx" = (
/obj/effect/decal/cleanable/generic,
/turf/open/floor/iron/grimy,
@@ -76059,6 +76094,12 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/service/chapel)
+"taR" = (
+/obj/machinery/cryo_cell{
+ dir = 8
+ },
+/turf/open/floor/iron/dark/textured_large,
+/area/station/medical/cryo)
"tbd" = (
/obj/item/radio/intercom/directional/west,
/obj/effect/turf_decal/tile/yellow/half/contrasted{
@@ -76190,10 +76231,6 @@
/obj/machinery/light/directional/south,
/turf/open/floor/iron,
/area/station/engineering/supermatter/room)
-"tcB" = (
-/obj/effect/decal/cleanable/oil,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"tcG" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -76894,16 +76931,6 @@
/obj/effect/turf_decal/tile/neutral,
/turf/open/floor/iron,
/area/station/hallway/primary/central/aft)
-"toy" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/cable,
-/obj/structure/disposalpipe/segment,
-/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"toB" = (
/obj/machinery/light/directional/west,
/obj/effect/turf_decal/stripes/line{
@@ -78958,26 +78985,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/science/server)
-"tNn" = (
-/obj/structure/cable,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/machinery/requests_console/directional/south{
- department = "Mining";
- name = "Mining Requests Console"
- },
-/obj/machinery/requests_console/directional/south{
- department = "Mining";
- name = "Mining Requests Console"
- },
-/obj/machinery/camera/directional/south{
- c_tag = "Cargo - Mining Dock";
- name = "cargo camera"
- },
-/obj/effect/turf_decal/tile/brown/half/contrasted,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"tNq" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -79292,6 +79299,17 @@
dir = 1
},
/area/station/service/bar)
+"tQr" = (
+/obj/structure/table,
+/obj/machinery/microwave{
+ desc = "Cooks and boils stuff, somehow.";
+ pixel_x = -3;
+ pixel_y = 5
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/bot,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"tQt" = (
/obj/structure/disposalpipe/segment{
dir = 6
@@ -81479,12 +81497,6 @@
},
/turf/open/floor/wood,
/area/station/command/heads_quarters/hop)
-"usJ" = (
-/obj/effect/turf_decal/tile/purple/half/contrasted{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"usZ" = (
/obj/item/flashlight/lamp,
/obj/machinery/airalarm/directional/east,
@@ -82116,6 +82128,15 @@
/obj/effect/turf_decal/tile/red,
/turf/open/floor/iron,
/area/station/security/execution/transfer)
+"uAH" = (
+/obj/structure/cable,
+/obj/structure/chair/office{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/purple/half/contrasted,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"uAI" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/landmark/start/depsec/engineering,
@@ -82160,21 +82181,6 @@
dir = 1
},
/area/station/medical/morgue)
-"uBd" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/disposalpipe/segment{
- dir = 6
- },
-/obj/structure/sign/nanotrasen{
- pixel_y = 32
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/hallway/primary/central/fore)
"uBf" = (
/obj/machinery/atmospherics/pipe/smart/manifold/purple/visible{
dir = 4
@@ -83164,18 +83170,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/commons/storage/primary)
-"uND" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/disposalpipe/segment{
- dir = 9
- },
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/delivery,
-/turf/open/floor/iron,
-/area/station/maintenance/starboard/fore)
"uNE" = (
/obj/machinery/atmospherics/components/unary/passive_vent{
dir = 4
@@ -83222,15 +83216,6 @@
},
/turf/open/floor/iron/white,
/area/station/science/ordnance/office)
-"uOk" = (
-/obj/structure/cable,
-/obj/structure/chair/office{
- dir = 4
- },
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/tile/purple/half/contrasted,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"uOn" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -86041,6 +86026,13 @@
},
/turf/open/floor/wood,
/area/station/service/library/abandoned)
+"vyF" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/landmark/start/shaft_miner,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"vyG" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -86117,6 +86109,18 @@
/obj/structure/sign/warning/secure_area/directional/north,
/turf/open/space,
/area/space/nearstation)
+"vzy" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/disposalpipe/segment{
+ dir = 9
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/delivery,
+/turf/open/floor/iron,
+/area/station/maintenance/starboard/fore)
"vzA" = (
/obj/effect/turf_decal/trimline/purple/filled/line,
/turf/open/floor/iron/white,
@@ -86450,12 +86454,6 @@
/obj/effect/turf_decal/tile/neutral/half/contrasted,
/turf/open/floor/iron,
/area/station/command/heads_quarters/hos)
-"vDj" = (
-/obj/structure/cable,
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/tile/purple/half/contrasted,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"vDm" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -86840,16 +86838,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/department/security)
-"vId" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/disposalpipe/segment,
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/delivery,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"vIq" = (
/obj/structure/cable,
/obj/structure/disposalpipe/junction{
@@ -87187,15 +87175,6 @@
},
/turf/open/floor/iron,
/area/station/security/checkpoint/engineering)
-"vNV" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/effect/turf_decal/tile/purple{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"vOh" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -87429,6 +87408,12 @@
/obj/machinery/light/small/directional/east,
/turf/open/floor/iron/dark,
/area/station/service/bar)
+"vQT" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"vRn" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/obj/structure/railing/corner,
@@ -88536,23 +88521,6 @@
/obj/effect/landmark/start/depsec/medical,
/turf/open/floor/iron/large,
/area/station/security/checkpoint/medical/medsci)
-"whb" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/cable,
-/obj/structure/disposalpipe/segment,
-/obj/machinery/door/firedoor,
-/obj/effect/turf_decal/stripes/line,
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/obj/machinery/door/airlock/mining/glass{
- name = "Delivery Office"
- },
-/obj/effect/mapping_helpers/airlock/access/any/supply/shipping,
-/obj/effect/mapping_helpers/airlock/access/any/supply/mining,
-/turf/open/floor/iron,
-/area/station/cargo/sorting)
"whc" = (
/obj/structure/sign/poster/official/fruit_bowl/directional/west,
/obj/effect/turf_decal/stripes/line{
@@ -88958,6 +88926,13 @@
},
/turf/open/floor/glass,
/area/station/maintenance/space_hut/observatory)
+"wml" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"wmn" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 8
@@ -89203,6 +89178,14 @@
/obj/effect/turf_decal/delivery,
/turf/open/floor/iron,
/area/station/hallway/secondary/entry)
+"woJ" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"woK" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -89576,6 +89559,13 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/starboard)
+"wsJ" = (
+/obj/machinery/cryo_cell{
+ dir = 8
+ },
+/obj/machinery/status_display/ai/directional/south,
+/turf/open/floor/iron/dark/textured_large,
+/area/station/medical/cryo)
"wsN" = (
/obj/machinery/door/airlock/command{
name = "Research Division Server Room"
@@ -89746,19 +89736,6 @@
},
/turf/open/floor/iron/white,
/area/station/science/ordnance/storage)
-"wuU" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/disposalpipe/segment{
- dir = 9
- },
-/obj/machinery/firealarm/directional/east,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj/machinery/light/small/directional/east,
-/turf/open/floor/iron,
-/area/station/hallway/primary/central/fore)
"wuV" = (
/obj/structure/fireaxecabinet/directional/south,
/obj/effect/turf_decal/tile/blue/half/contrasted,
@@ -89987,6 +89964,11 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
+"wxL" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/landmark/event_spawn,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"wyh" = (
/obj/structure/disposalpipe/segment{
dir = 10
@@ -90364,6 +90346,14 @@
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/plating,
/area/station/maintenance/department/engine/atmos)
+"wCA" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/structure/disposalpipe/segment,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"wCB" = (
/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible,
/obj/effect/turf_decal/stripes/line{
@@ -91942,6 +91932,14 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/security/lockers)
+"xaN" = (
+/obj/structure/cable,
+/obj/effect/turf_decal/bot,
+/obj/structure/table,
+/obj/item/storage/medkit/regular,
+/obj/machinery/power/apc/auto_name/directional/west,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"xaP" = (
/obj/effect/turf_decal/tile/neutral{
dir = 8
@@ -95073,15 +95071,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/ai)
-"xMZ" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/effect/turf_decal/tile/brown{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"xNe" = (
/obj/structure/lattice,
/obj/structure/grille/broken,
@@ -95637,12 +95626,6 @@
/obj/structure/barricade/wooden,
/turf/open/floor/plating,
/area/station/service/abandoned_gambling_den)
-"xVv" = (
-/obj/effect/turf_decal/tile/purple/half/contrasted{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"xVI" = (
/obj/structure/rack,
/obj/item/analyzer,
@@ -96190,6 +96173,15 @@
/obj/machinery/airalarm/directional/west,
/turf/open/floor/iron,
/area/station/science/robotics/mechbay)
+"ydr" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/purple{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"ydE" = (
/obj/structure/chair/stool/directional/south,
/obj/effect/decal/cleanable/dirt,
@@ -96579,6 +96571,14 @@
},
/turf/open/floor/iron/white,
/area/station/science/lab)
+"yiG" = (
+/obj/structure/cable,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/purple/half/contrasted,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"yiK" = (
/obj/item/kirbyplants/organic/plant21,
/obj/effect/turf_decal/delivery,
@@ -138788,7 +138788,7 @@ hoC
yfI
bGf
kGo
-sCW
+nXf
xhW
ygL
xhW
@@ -139541,7 +139541,7 @@ kRn
kjl
lDi
lDi
-sLg
+eKS
bqv
hDZ
bfT
@@ -139629,9 +139629,9 @@ cwe
ltS
cwe
oDE
-fUr
+taR
bcj
-pDy
+wsJ
oDE
ajY
tJh
@@ -139811,7 +139811,7 @@ mOe
yhh
liD
mZU
-whb
+jUy
uBZ
pso
sqW
@@ -140328,8 +140328,8 @@ gLz
xhW
axz
fOz
-rAl
-bkr
+fUl
+jCR
yfo
qLp
pcx
@@ -140591,8 +140591,8 @@ xhW
xhW
xhW
xhW
-uBd
-wuU
+jjK
+jtE
vPp
tJT
qzY
@@ -140840,13 +140840,13 @@ uSp
oSv
cFz
rWo
-qko
-vNV
-pxS
-xMZ
-mlF
-qsF
-jKY
+ctR
+ydr
+gDE
+dsq
+atk
+ohR
+xaN
tpZ
lDY
tpZ
@@ -141096,16 +141096,16 @@ qaF
tQW
hQj
uzM
-aPD
-stf
-llj
-mDm
-fbu
-mDm
-vDj
-cwd
+fsg
+eIA
+dtp
+cQO
+wml
+cQO
+nTw
+lBB
tpZ
-qmT
+dri
tpZ
aaa
aad
@@ -141353,16 +141353,16 @@ rbV
qLg
uTu
tQP
-rmH
-toy
-izj
-fAj
-pUs
-okN
-oAV
-vId
+fnN
+mcK
+ltB
+wCA
+nsI
+cze
+ihc
+bNi
qyX
-uND
+vzy
tpZ
aaa
lhY
@@ -141612,14 +141612,14 @@ cSK
pok
rWo
llJ
-kKx
-dux
-tcB
-nEE
-cyc
-rQF
+fCb
+vyF
+dih
+vQT
+yiG
+oea
tpZ
-eFU
+nos
tpZ
aad
lhY
@@ -141868,15 +141868,15 @@ fKA
krp
krp
aJE
-mtL
-kKx
-iXd
-eYt
-hzs
-tNn
-cGV
+kzi
+fCb
+fZz
+oml
+qyO
+eld
+oWV
tpZ
-jRc
+nro
tpZ
aaa
lhY
@@ -142125,15 +142125,15 @@ jmp
iWR
gkP
krp
-kTs
-ljQ
-guj
-eYt
-nhj
-owZ
-bLN
+gdD
+iWJ
+fJm
+oml
+ksL
+sxu
+aSj
tpZ
-elO
+gUe
tpZ
aaa
lhY
@@ -142382,15 +142382,15 @@ xPf
xZC
aiF
aJE
-jCu
-iio
-mDm
-sgK
-mDm
-gco
-hkn
+snh
+dIz
+cQO
+wxL
+cQO
+grT
+aLg
tpZ
-cwK
+dcA
tpZ
aaa
lhY
@@ -142639,12 +142639,12 @@ osw
qZD
qrG
aJE
-dPC
-usJ
-nhj
-mDm
-mDm
-uOk
+tQr
+gGM
+ksL
+cQO
+cQO
+uAH
bhJ
tpZ
tpZ
@@ -142896,12 +142896,12 @@ uQZ
xhJ
vMd
tgX
-jfO
-jBM
-xVv
-ftS
-dXs
-rgC
+fwD
+dRf
+ofM
+woJ
+aWe
+rKu
tDD
rWo
aad
diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
index f3ff89fcc80..5ae6d741a2a 100644
--- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm
+++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
@@ -2960,12 +2960,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central)
-"aVE" = (
-/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
- dir = 4
- },
-/turf/open/floor/iron/dark,
-/area/station/cargo/miningdock)
"aVF" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/obj/effect/turf_decal/tile/red{
@@ -4456,12 +4450,6 @@
},
/turf/open/floor/iron/dark,
/area/mine/storage)
-"bsx" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"bsG" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/research/glass{
@@ -5224,6 +5212,20 @@
/obj/item/storage/box/monkeycubes,
/turf/open/floor/iron,
/area/station/science/xenobiology)
+"bCM" = (
+/obj/machinery/requests_console/directional/north{
+ department = "Cargo Bay";
+ name = "Cargo Bay Requests Console"
+ },
+/obj/effect/mapping_helpers/requests_console/supplies,
+/obj/structure/table,
+/obj/item/hand_labeler,
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/obj/item/folder/yellow,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"bCQ" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
@@ -7182,6 +7184,12 @@
},
/turf/open/floor/iron,
/area/station/engineering/atmos)
+"cfR" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"cfS" = (
/obj/item/clothing/suit/costume/snowman{
name = "Man of Snow"
@@ -9395,6 +9403,16 @@
/obj/effect/mapping_helpers/airlock/access/all/security/brig,
/turf/open/floor/iron/dark/textured,
/area/station/security/lockers)
+"cLI" = (
+/obj/structure/rack,
+/obj/item/shovel{
+ pixel_x = -5
+ },
+/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"cLJ" = (
/obj/structure/table/wood,
/obj/item/paper{
@@ -10033,6 +10051,11 @@
},
/turf/open/floor/iron,
/area/station/security/prison/garden)
+"cWr" = (
+/obj/effect/landmark/start/shaft_miner,
+/obj/structure/cable,
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"cWG" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -10697,10 +10720,6 @@
},
/turf/open/floor/plating/snowed/smoothed/icemoon,
/area/icemoon/underground/explored)
-"dgf" = (
-/obj/machinery/firealarm/directional/north,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"dgl" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 8
@@ -12261,6 +12280,11 @@
/obj/effect/turf_decal/tile/blue/half/contrasted,
/turf/open/floor/iron,
/area/station/command/bridge)
+"dEJ" = (
+/obj/machinery/light_switch/directional/north,
+/obj/machinery/light/directional/north,
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"dEQ" = (
/obj/machinery/camera/directional/east{
c_tag = "Public Mining Ladder"
@@ -12890,13 +12914,6 @@
/obj/effect/turf_decal/tile/dark_blue/diagonal_edge,
/turf/open/floor/iron/dark/diagonal,
/area/station/engineering/atmos/storage)
-"dPn" = (
-/obj/structure/rack,
-/obj/item/pickaxe{
- pixel_x = 5
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"dPy" = (
/obj/machinery/camera/directional/west{
c_tag = "Xenobiology Kill Chamber";
@@ -13174,13 +13191,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/freezer,
/area/mine/laborcamp)
-"dUK" = (
-/obj/machinery/camera/directional/west{
- c_tag = "Mining Dock"
- },
-/obj/machinery/computer/security/mining,
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"dUL" = (
/obj/machinery/door/poddoor/preopen{
id = "maint1"
@@ -13209,15 +13219,6 @@
/obj/structure/sign/poster/random/directional/east,
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
-"dVs" = (
-/obj/structure/table,
-/obj/item/paper_bin{
- pixel_x = 1;
- pixel_y = 9
- },
-/obj/machinery/mining_weather_monitor/directional/west,
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"dVt" = (
/obj/structure/chair/stool/directional/west,
/turf/open/floor/iron/checker,
@@ -14878,11 +14879,6 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/iron,
/area/station/maintenance/department/medical/central)
-"ewq" = (
-/obj/machinery/light_switch/directional/north,
-/obj/machinery/light/directional/north,
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"ewz" = (
/obj/structure/window/reinforced/spawner/directional/east,
/obj/structure/window/reinforced/spawner/directional/north,
@@ -15930,6 +15926,13 @@
},
/turf/open/floor/iron/white,
/area/station/science/research)
+"eNM" = (
+/obj/machinery/cryo_cell,
+/obj/effect/turf_decal/stripes/line{
+ dir = 10
+ },
+/turf/open/floor/iron/dark/textured,
+/area/station/medical/cryo)
"eNQ" = (
/obj/structure/sign/warning/vacuum/directional/south,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
@@ -16861,10 +16864,6 @@
/obj/item/seeds/apple,
/turf/open/floor/iron,
/area/mine/laborcamp)
-"feB" = (
-/obj/machinery/airalarm/directional/east,
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"feJ" = (
/turf/closed/wall/r_wall,
/area/station/ai_monitored/security/armory/upper)
@@ -18953,12 +18952,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/green/visible,
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
-"fNx" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"fNy" = (
/obj/structure/rack,
/obj/item/clothing/suit/hooded/wintercoat{
@@ -20952,6 +20945,13 @@
/obj/structure/window/reinforced/spawner/directional/south,
/turf/open/floor/iron,
/area/station/science/xenobiology)
+"gvZ" = (
+/obj/machinery/rnd/bepis,
+/obj/effect/turf_decal/stripes/line{
+ dir = 6
+ },
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"gwm" = (
/obj/machinery/door/firedoor/heavy,
/turf/open/floor/iron/white/side{
@@ -20992,6 +20992,17 @@
},
/turf/open/floor/iron/cafeteria,
/area/station/commons/dorms/laundry)
+"gwB" = (
+/obj/machinery/door/firedoor,
+/obj/machinery/door/airlock/mining{
+ name = "Mining Dock"
+ },
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/mapping_helpers/airlock/access/all/supply/mining,
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"gwJ" = (
/obj/effect/turf_decal/stripes/asteroid/line{
dir = 5
@@ -21146,12 +21157,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/aisat_interior)
-"gzN" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"gzV" = (
/obj/structure/mineral_door/paperframe{
name = "Meditation Room"
@@ -24199,6 +24204,13 @@
/obj/effect/turf_decal/tile/blue/full,
/turf/open/floor/iron/large,
/area/station/medical/treatment_center)
+"hxC" = (
+/obj/structure/rack,
+/obj/item/pickaxe{
+ pixel_x = 5
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"hxE" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -28356,6 +28368,15 @@
dir = 1
},
/area/station/service/hydroponics)
+"iNu" = (
+/obj/structure/table,
+/obj/item/paper_bin{
+ pixel_x = 1;
+ pixel_y = 9
+ },
+/obj/machinery/mining_weather_monitor/directional/west,
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"iNy" = (
/obj/structure/chair{
dir = 4
@@ -29599,6 +29620,12 @@
/obj/structure/tank_holder/extinguisher,
/turf/open/floor/iron/white,
/area/station/medical/medbay/aft)
+"jiK" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"jjk" = (
/obj/structure/lattice/catwalk,
/obj/structure/railing{
@@ -31736,7 +31763,7 @@
"jRB" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/table_frame,
-/obj/item/wirerod,
+/obj/item/melee/baton/security/cattleprod,
/obj/effect/spawner/random/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
@@ -33544,13 +33571,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central)
-"krx" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell,
-/obj/effect/turf_decal/stripes/line{
- dir = 10
- },
-/turf/open/floor/iron/dark/textured,
-/area/station/medical/cryo)
"kry" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -34148,6 +34168,14 @@
/obj/effect/spawner/random/structure/grille,
/turf/open/floor/plating,
/area/station/maintenance/department/chapel)
+"kAq" = (
+/obj/machinery/cryo_cell,
+/obj/effect/turf_decal/stripes/line{
+ dir = 6
+ },
+/obj/item/radio/intercom/directional/east,
+/turf/open/floor/iron/dark/textured,
+/area/station/medical/cryo)
"kAC" = (
/obj/structure/reagent_dispensers/watertank,
/obj/effect/decal/cleanable/cobweb/cobweb2,
@@ -34772,6 +34800,10 @@
/obj/structure/sign/poster/official/random/directional/north,
/turf/open/floor/iron/smooth,
/area/mine/laborcamp/security)
+"kJz" = (
+/obj/machinery/firealarm/directional/east,
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"kJI" = (
/obj/structure/transit_tube/station/reverse,
/turf/open/floor/plating,
@@ -35228,11 +35260,6 @@
/obj/structure/sign/warning/bodysposal/directional/south,
/turf/open/floor/iron/white,
/area/station/medical/surgery/aft)
-"kQL" = (
-/obj/machinery/power/apc/auto_name/directional/north,
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"kQM" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 5
@@ -36893,6 +36920,13 @@
},
/turf/open/floor/plating,
/area/station/maintenance/starboard/lesser)
+"lqt" = (
+/obj/structure/table,
+/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"lqz" = (
/obj/structure/cable,
/turf/closed/wall,
@@ -37024,14 +37058,6 @@
},
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/aisat/service)
-"lti" = (
-/obj/structure/table,
-/obj/effect/turf_decal/tile/brown/half/contrasted{
- dir = 8
- },
-/obj/machinery/light/small/directional/west,
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"ltk" = (
/obj/effect/mapping_helpers/airlock/cyclelink_helper{
dir = 8
@@ -40328,6 +40354,11 @@
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
+"mwF" = (
+/obj/machinery/power/apc/auto_name/directional/north,
+/obj/structure/cable,
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"mwQ" = (
/obj/structure/tank_holder/extinguisher,
/turf/open/floor/plating,
@@ -41950,6 +41981,15 @@
/obj/machinery/light/built/directional/east,
/turf/open/floor/iron/white,
/area/station/maintenance/port/fore)
+"mZt" = (
+/obj/structure/closet/crate,
+/obj/item/radio/intercom/directional/east,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/machinery/light/small/directional/north,
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"mZu" = (
/obj/structure/table/glass,
/obj/item/cultivator,
@@ -42037,16 +42077,6 @@
/obj/machinery/light/directional/north,
/turf/open/floor/iron,
/area/station/engineering/storage)
-"naO" = (
-/obj/structure/rack,
-/obj/item/shovel{
- pixel_x = -5
- },
-/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"naP" = (
/obj/structure/chair/comfy/black{
dir = 4
@@ -43765,17 +43795,6 @@
},
/turf/closed/wall/r_wall,
/area/station/engineering/transit_tube)
-"nyB" = (
-/obj/structure/table,
-/obj/item/folder/yellow,
-/obj/item/pen,
-/obj/machinery/requests_console/directional/west{
- department = "Mining";
- name = "Mining Requests Console"
- },
-/obj/effect/mapping_helpers/requests_console/supplies,
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"nyC" = (
/turf/open/floor/iron/dark/smooth_half,
/area/station/service/chapel)
@@ -44806,17 +44825,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/white,
/area/station/science/research)
-"nMB" = (
-/obj/machinery/door/firedoor,
-/obj/machinery/door/airlock/mining{
- name = "Mining Dock"
- },
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/mapping_helpers/airlock/access/all/supply/mining,
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"nME" = (
/obj/item/clothing/head/utility/hardhat,
/turf/open/floor/plating/snowed/icemoon,
@@ -48145,6 +48153,14 @@
/obj/machinery/airalarm/directional/west,
/turf/open/floor/iron/dark,
/area/station/engineering/supermatter/room)
+"oOa" = (
+/obj/structure/table,
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 8
+ },
+/obj/machinery/light/small/directional/west,
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"oOb" = (
/obj/structure/sign/warning/fire/directional/north,
/turf/open/floor/glass/reinforced,
@@ -48595,11 +48611,6 @@
/obj/machinery/light/small/directional/east,
/turf/open/floor/iron/freezer,
/area/station/commons/toilet)
-"oVf" = (
-/obj/effect/landmark/start/shaft_miner,
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"oVt" = (
/obj/machinery/power/apc/auto_name/directional/south,
/obj/structure/cable,
@@ -49546,14 +49557,6 @@
},
/turf/open/floor/iron/smooth_large,
/area/station/cargo/warehouse)
-"piX" = (
-/obj/machinery/camera/directional/north{
- c_tag = "Cargo Bay North"
- },
-/obj/machinery/vending/wardrobe/cargo_wardrobe,
-/obj/machinery/light/directional/north,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"pja" = (
/obj/structure/rack,
/obj/item/pickaxe,
@@ -49779,6 +49782,13 @@
/obj/structure/flora/grass/brown/style_random,
/turf/open/misc/asteroid/snow/standard_air,
/area/station/science/research)
+"pnr" = (
+/obj/structure/chair/office{
+ dir = 8
+ },
+/obj/effect/landmark/start/shaft_miner,
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"pnz" = (
/obj/item/radio/intercom/directional/west,
/turf/open/floor/iron,
@@ -51952,20 +51962,6 @@
},
/turf/open/floor/iron,
/area/station/tcommsat/computer)
-"pVC" = (
-/obj/machinery/requests_console/directional/north{
- department = "Cargo Bay";
- name = "Cargo Bay Requests Console"
- },
-/obj/effect/mapping_helpers/requests_console/supplies,
-/obj/structure/table,
-/obj/item/hand_labeler,
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/obj/item/folder/yellow,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"pVH" = (
/turf/closed/wall/mineral/wood,
/area/station/maintenance/aft/lesser)
@@ -53418,14 +53414,6 @@
/obj/machinery/light/directional/north,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/underground/explored)
-"qtT" = (
-/obj/machinery/door/airlock/mining/glass{
- name = "Mining Dock"
- },
-/obj/machinery/door/firedoor,
-/obj/effect/mapping_helpers/airlock/access/all/supply/mining,
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"que" = (
/obj/machinery/camera/directional/south{
c_tag = "Chapel South"
@@ -54424,10 +54412,6 @@
/obj/item/cigbutt,
/turf/open/floor/wood/large,
/area/mine/eva/lower)
-"qJJ" = (
-/obj/machinery/firealarm/directional/east,
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"qJT" = (
/obj/machinery/light/small/directional/south,
/turf/open/floor/plating/snowed/icemoon,
@@ -54897,6 +54881,12 @@
"qPL" = (
/turf/closed/wall/r_wall,
/area/station/hallway/secondary/exit/departure_lounge)
+"qPR" = (
+/obj/effect/turf_decal/stripes/corner{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"qPX" = (
/obj/structure/sink/directional/west,
/obj/structure/mirror/directional/east,
@@ -55412,15 +55402,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/fore/lesser)
-"qYc" = (
-/obj/structure/closet/crate,
-/obj/item/radio/intercom/directional/east,
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/obj/machinery/light/small/directional/north,
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"qYh" = (
/obj/structure/chair/pew{
dir = 1
@@ -55538,6 +55519,12 @@
/obj/machinery/firealarm/directional/south,
/turf/open/floor/iron/textured,
/area/mine/mechbay)
+"qZY" = (
+/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
+ dir = 4
+ },
+/turf/open/floor/iron/dark,
+/area/station/cargo/miningdock)
"rab" = (
/obj/structure/reagent_dispensers/fueltank,
/turf/open/floor/plating,
@@ -57206,6 +57193,14 @@
/obj/item/stack/license_plates/empty/fifty,
/turf/open/floor/iron/dark/smooth_half,
/area/station/security/prison/work)
+"rBz" = (
+/obj/machinery/door/airlock/mining/glass{
+ name = "Mining Dock"
+ },
+/obj/machinery/door/firedoor,
+/obj/effect/mapping_helpers/airlock/access/all/supply/mining,
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"rBL" = (
/obj/machinery/light/directional/west,
/turf/open/openspace,
@@ -59421,14 +59416,6 @@
/obj/effect/turf_decal/tile/yellow/opposingcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/project)
-"slK" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell,
-/obj/effect/turf_decal/stripes/line{
- dir = 6
- },
-/obj/item/radio/intercom/directional/east,
-/turf/open/floor/iron/dark/textured,
-/area/station/medical/cryo)
"slX" = (
/obj/structure/fans/tiny,
/obj/effect/turf_decal/stripes/red/box,
@@ -62895,13 +62882,6 @@
/obj/item/key/janitor,
/turf/open/floor/iron,
/area/station/service/janitor)
-"tqC" = (
-/obj/structure/table,
-/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"tqQ" = (
/obj/effect/turf_decal/stripes/corner{
dir = 1
@@ -63421,13 +63401,6 @@
/obj/structure/chair/office,
/turf/open/floor/wood,
/area/station/service/library)
-"tyH" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/landmark/event_spawn,
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"tyK" = (
/obj/item/mop,
/obj/item/reagent_containers/cup/bucket,
@@ -64482,6 +64455,10 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/mix)
+"tOz" = (
+/obj/structure/cable,
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"tOF" = (
/obj/structure/chair/comfy/black{
dir = 8
@@ -64857,6 +64834,13 @@
/obj/structure/table,
/turf/open/floor/plating/snowed/coldroom,
/area/station/service/kitchen/coldroom)
+"tWF" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/landmark/event_spawn,
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"tWK" = (
/obj/structure/cable,
/turf/open/floor/plating/snowed/icemoon,
@@ -66129,6 +66113,17 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/white,
/area/station/science/research)
+"use" = (
+/obj/structure/table,
+/obj/item/folder/yellow,
+/obj/item/pen,
+/obj/machinery/requests_console/directional/west{
+ department = "Mining";
+ name = "Mining Requests Console"
+ },
+/obj/effect/mapping_helpers/requests_console/supplies,
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"uso" = (
/obj/structure/closet/crate/trashcart,
/obj/effect/spawner/random/contraband/prison,
@@ -68315,13 +68310,6 @@
},
/turf/open/floor/iron/grimy,
/area/station/security/prison/work)
-"veh" = (
-/obj/machinery/rnd/bepis,
-/obj/effect/turf_decal/stripes/line{
- dir = 6
- },
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"vek" = (
/obj/effect/turf_decal/weather/snow/corner,
/obj/machinery/light/small/directional/north,
@@ -68476,10 +68464,6 @@
/obj/effect/turf_decal/trimline/blue/filled/line,
/turf/open/floor/iron/white,
/area/station/medical/medbay/aft)
-"vgC" = (
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"vgD" = (
/obj/structure/rack,
/obj/item/stack/sheet/iron/fifty,
@@ -68513,6 +68497,10 @@
/obj/machinery/firealarm/directional/north,
/turf/open/floor/iron/dark,
/area/station/service/chapel)
+"vhn" = (
+/obj/machinery/firealarm/directional/north,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"vhr" = (
/mob/living/simple_animal/hostile/retaliate/goat{
atmos_requirements = list("min_oxy"=1,"max_oxy"=0,"min_plas"=0,"max_plas"=1,"min_co2"=0,"max_co2"=5,"min_n2"=0,"max_n2"=0);
@@ -68712,6 +68700,10 @@
/obj/structure/sign/poster/random/directional/west,
/turf/open/floor/iron/large,
/area/station/service/kitchen/diner)
+"vlu" = (
+/obj/machinery/airalarm/directional/east,
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"vlI" = (
/obj/effect/turf_decal/siding/white{
dir = 4
@@ -70969,13 +70961,6 @@
/obj/item/book/bible,
/turf/open/floor/iron/chapel,
/area/station/service/chapel)
-"vWV" = (
-/obj/structure/chair/office{
- dir = 8
- },
-/obj/effect/landmark/start/shaft_miner,
-/turf/open/floor/iron,
-/area/station/cargo/miningdock)
"vWW" = (
/obj/effect/turf_decal/tile/neutral/opposingcorners,
/turf/open/floor/iron,
@@ -72717,6 +72702,14 @@
/obj/effect/mapping_helpers/airlock/access/all/service/lawyer,
/turf/open/floor/wood,
/area/station/service/lawoffice)
+"wxd" = (
+/obj/machinery/camera/directional/north{
+ c_tag = "Cargo Bay North"
+ },
+/obj/machinery/vending/wardrobe/cargo_wardrobe,
+/obj/machinery/light/directional/north,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"wxg" = (
/turf/open/floor/iron/freezer,
/area/mine/laborcamp)
@@ -72799,6 +72792,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
/area/station/maintenance/port/greater)
+"wyv" = (
+/obj/machinery/camera/directional/west{
+ c_tag = "Mining Dock"
+ },
+/obj/machinery/computer/security/mining,
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"wyB" = (
/obj/machinery/conveyor{
dir = 1;
@@ -74860,12 +74860,6 @@
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/medical/storage)
-"xdz" = (
-/obj/effect/turf_decal/stripes/corner{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"xdA" = (
/obj/effect/turf_decal/siding/white{
dir = 4
@@ -75935,6 +75929,12 @@
},
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"xuh" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/cable,
+/turf/open/floor/iron,
+/area/station/cargo/miningdock)
"xun" = (
/obj/machinery/door/poddoor/massdriver_chapel,
/obj/structure/fans/tiny,
@@ -229061,8 +229061,8 @@ xqX
bCQ
wBb
tKI
-veh
-gzN
+gvZ
+jiK
ajw
ajw
mmi
@@ -229318,8 +229318,8 @@ sIM
yjn
wBb
tKI
-pVC
-xdz
+bCM
+qPR
kXs
ajw
mmi
@@ -229832,7 +229832,7 @@ nAr
nAr
wNR
tKI
-piX
+wxd
ajw
ajw
ajw
@@ -230363,7 +230363,7 @@ pYT
maT
bln
qjQ
-aVE
+qZY
qxb
nrm
hoD
@@ -230878,7 +230878,7 @@ bln
bln
bln
qjQ
-qYc
+mZt
hxE
xtr
qjQ
@@ -231128,7 +231128,7 @@ kXr
kXr
kXr
kXr
-dgf
+vhn
ajw
kXr
bln
@@ -231386,15 +231386,15 @@ lZQ
wXR
qjQ
aOd
-qtT
+rBz
aOd
qjQ
qjQ
qjQ
-tqC
-lti
+lqt
+oOa
jBf
-naO
+cLI
qjQ
sEB
sEB
@@ -231642,16 +231642,16 @@ oDt
kRU
oQa
qjQ
-kQL
-vgC
+mwF
+tOz
hoD
-dVs
-nyB
-dUK
+iNu
+use
+wyv
hoD
hoD
hxE
-dPn
+hxC
aOd
bln
bln
@@ -231899,12 +231899,12 @@ uxl
oRy
aHC
qjQ
-ewq
-oVf
+dEJ
+cWr
hoD
hoD
-vWV
-fNx
+pnr
+cfR
hoD
iVA
hxE
@@ -232155,10 +232155,10 @@ mOA
cHb
psW
psW
-nMB
+gwB
hxE
hxE
-tyH
+tWF
hxE
hxE
hxE
@@ -232414,9 +232414,9 @@ rLu
nRq
aOd
hoD
-bsx
+xuh
hoD
-qJJ
+kJz
hxE
hoD
hoD
@@ -232675,7 +232675,7 @@ lNG
nZh
tue
hxE
-feB
+vlu
lis
aud
lis
@@ -250147,7 +250147,7 @@ oyy
amE
wyj
klc
-krx
+eNM
ufN
vCz
ufN
@@ -250661,7 +250661,7 @@ qhN
amE
lei
klc
-slK
+kAq
hXU
oRu
hIe
diff --git a/_maps/map_files/KiloStation2/KiloStation2.dmm b/_maps/map_files/KiloStation2/KiloStation2.dmm
index 8e20d8b305b..aefa21efb19 100644
--- a/_maps/map_files/KiloStation2/KiloStation2.dmm
+++ b/_maps/map_files/KiloStation2/KiloStation2.dmm
@@ -7412,7 +7412,7 @@
/turf/open/misc/asteroid/airless,
/area/space/nearstation)
"cuj" = (
-/mob/living/simple_animal/hostile/asteroid/hivelord,
+/mob/living/basic/mining/hivelord,
/turf/open/misc/asteroid/airless,
/area/space/nearstation)
"cup" = (
@@ -23697,7 +23697,7 @@
/turf/open/floor/iron/dark,
/area/station/hallway/secondary/entry)
"hHg" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell{
+/obj/machinery/cryo_cell{
dir = 4
},
/obj/effect/turf_decal/delivery,
@@ -29122,7 +29122,7 @@
/obj/structure/table,
/obj/effect/decal/cleanable/cobweb/cobweb2,
/obj/item/storage/toolbox/emergency,
-/obj/item/wirerod,
+/obj/item/melee/baton/security/cattleprod,
/obj/machinery/light/small/directional/north,
/obj/item/radio/intercom/directional/east,
/turf/open/floor/iron/dark,
@@ -29946,7 +29946,7 @@
/area/station/command/bridge)
"jBO" = (
/obj/effect/turf_decal/bot,
-/obj/machinery/atmospherics/components/unary/cryo_cell{
+/obj/machinery/cryo_cell{
dir = 4
},
/obj/effect/turf_decal/tile/neutral/half/contrasted{
@@ -39033,7 +39033,7 @@
/obj/item/wirecutters{
pixel_y = 5
},
-/obj/item/wirerod,
+/obj/item/melee/baton/security/cattleprod,
/obj/effect/turf_decal/bot,
/turf/open/floor/iron/dark,
/area/station/security/interrogation)
@@ -69836,7 +69836,7 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 8
},
-/mob/living/simple_animal/hostile/asteroid/hivelord,
+/mob/living/basic/mining/hivelord,
/turf/open/floor/plating,
/area/station/cargo/warehouse)
"wpw" = (
@@ -70490,7 +70490,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 1
},
-/mob/living/simple_animal/hostile/asteroid/hivelord,
+/mob/living/basic/mining/hivelord,
/turf/open/floor/plating,
/area/station/cargo/warehouse)
"wAz" = (
@@ -75260,7 +75260,7 @@
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/ai_upload)
"ycp" = (
-/mob/living/simple_animal/hostile/asteroid/hivelord,
+/mob/living/basic/mining/hivelord,
/turf/open/misc/asteroid/lowpressure,
/area/space/nearstation)
"ycr" = (
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index cfa13aef72e..ebcfba29362 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -3334,13 +3334,6 @@
/obj/structure/extinguisher_cabinet/directional/north,
/turf/open/floor/iron,
/area/station/hallway/primary/starboard)
-"bje" = (
-/obj/structure/closet/emcloset,
-/obj/structure/disposalpipe/segment{
- dir = 5
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"bjl" = (
/obj/machinery/rnd/production/techfab/department/service,
/obj/effect/turf_decal/trimline/brown/warning{
@@ -4523,12 +4516,6 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/maintenance/fore)
-"bDS" = (
-/obj/structure/chair/office/light,
-/obj/structure/cable,
-/obj/item/stamp/head/cmo,
-/turf/open/floor/iron/white,
-/area/station/command/heads_quarters/cmo)
"bDW" = (
/turf/closed/wall,
/area/station/maintenance/department/engine)
@@ -4674,18 +4661,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
/area/station/maintenance/starboard/lesser)
-"bGM" = (
-/obj/machinery/door/airlock/mining{
- name = "Mining Office"
- },
-/obj/machinery/door/firedoor,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/disposalpipe/segment,
-/obj/effect/mapping_helpers/airlock/access/all/supply/mining,
-/obj/effect/landmark/navigate_destination,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"bHb" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -7192,14 +7167,6 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/station/security/brig)
-"cGL" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/disposalpipe/sorting/mail/flip{
- dir = 1
- },
-/obj/effect/mapping_helpers/mail_sorting/supply/disposals,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"cGV" = (
/obj/machinery/air_sensor/plasma_tank,
/turf/open/floor/engine/plasma,
@@ -9293,10 +9260,6 @@
},
/turf/open/floor/iron/cafeteria,
/area/station/engineering/atmos)
-"dwA" = (
-/obj/structure/disposalpipe/segment,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"dwJ" = (
/obj/structure/lattice,
/obj/effect/spawner/random/structure/grille,
@@ -9553,6 +9516,13 @@
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/plating/airless,
/area/station/solars/starboard/fore)
+"dDR" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/segment{
+ dir = 6
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"dDZ" = (
/obj/machinery/door/airlock/external{
name = "Common Mining Dock"
@@ -10961,14 +10931,6 @@
/obj/docking_port/stationary/escape_pod,
/turf/open/space/basic,
/area/space)
-"edo" = (
-/obj/structure/table/glass,
-/obj/item/paper_bin,
-/obj/item/clipboard,
-/obj/item/toy/figure/cmo,
-/obj/structure/cable,
-/turf/open/floor/iron/white,
-/area/station/command/heads_quarters/cmo)
"edq" = (
/obj/machinery/light/small/directional/west,
/obj/structure/cable,
@@ -11025,15 +10987,6 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/plating,
/area/station/cargo/sorting)
-"edP" = (
-/obj/structure/disposalpipe/segment,
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"edQ" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -12233,6 +12186,13 @@
/obj/structure/cable,
/turf/open/floor/iron/freezer,
/area/station/security/prison/shower)
+"exq" = (
+/obj/effect/decal/cleanable/blood/tracks{
+ dir = 4
+ },
+/obj/effect/spawner/random/structure/grille,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"exr" = (
/obj/structure/table/wood,
/obj/item/paper_bin{
@@ -12458,11 +12418,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/aft)
-"eEb" = (
-/obj/structure/cable,
-/obj/effect/mapping_helpers/broken_floor,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"eEf" = (
/obj/machinery/camera/directional/north{
c_tag = "Bar - Backroom"
@@ -14975,13 +14930,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/station/maintenance/disposal/incinerator)
-"fBl" = (
-/obj/structure/cable,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"fBo" = (
/obj/machinery/door/window/left/directional/north{
dir = 8;
@@ -15624,14 +15572,6 @@
/obj/machinery/light/small/directional/north,
/turf/open/floor/iron/white,
/area/station/science/explab)
-"fNH" = (
-/obj/machinery/door/airlock/maintenance{
- name = "Mining Dock Maintenance"
- },
-/obj/structure/cable,
-/obj/effect/mapping_helpers/airlock/access/all/supply/mining,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"fNI" = (
/obj/structure/sign/poster/contraband/random/directional/east,
/turf/open/floor/wood,
@@ -16653,6 +16593,11 @@
/obj/machinery/vending/wardrobe/jani_wardrobe,
/turf/open/floor/iron,
/area/station/service/janitor)
+"gjY" = (
+/obj/structure/reagent_dispensers/fueltank,
+/obj/structure/sign/poster/contraband/random/directional/north,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"gjZ" = (
/obj/effect/turf_decal/trimline/red/filled/line{
dir = 8
@@ -17321,12 +17266,6 @@
"guX" = (
/turf/closed/wall,
/area/station/commons/storage/primary)
-"guZ" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/disposalpipe/segment,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"gva" = (
/obj/effect/turf_decal/delivery,
/turf/open/floor/iron,
@@ -18437,12 +18376,6 @@
/obj/machinery/atmospherics/pipe/smart/simple/yellow/visible,
/turf/open/space/basic,
/area/space/nearstation)
-"gQv" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"gQw" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/stripes/white/line,
@@ -20978,6 +20911,11 @@
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/plating,
/area/station/maintenance/aft/lesser)
+"hNS" = (
+/obj/structure/cable,
+/obj/effect/mapping_helpers/broken_floor,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"hOh" = (
/obj/effect/turf_decal/trimline/red/filled/line,
/obj/effect/turf_decal/trimline/brown/filled/warning,
@@ -21668,6 +21606,13 @@
/obj/machinery/seed_extractor,
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
+"iaA" = (
+/obj/structure/cable,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"iaK" = (
/obj/effect/turf_decal/tile/yellow/half/contrasted,
/obj/machinery/light/directional/south,
@@ -23164,6 +23109,12 @@
/obj/effect/spawner/random/techstorage/medical_all,
/turf/open/floor/iron/dark,
/area/station/engineering/storage/tech)
+"izi" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/mapping_helpers/broken_floor,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"izl" = (
/obj/machinery/duct,
/obj/structure/disposalpipe/segment{
@@ -23338,6 +23289,14 @@
/obj/machinery/holopad,
/turf/open/floor/wood,
/area/station/service/cafeteria)
+"iBx" = (
+/obj/machinery/vending/wardrobe/cargo_wardrobe,
+/obj/effect/turf_decal/tile/brown/half/contrasted{
+ dir = 8
+ },
+/obj/machinery/light/small/directional/west,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"iBL" = (
/obj/structure/table/wood,
/turf/open/floor/wood,
@@ -24178,6 +24137,10 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/security/brig)
+"iPY" = (
+/obj/structure/disposalpipe/segment,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"iQd" = (
/obj/machinery/door/poddoor/shutters{
id = "supplybridge"
@@ -25904,14 +25867,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/storage/tech)
-"jty" = (
-/obj/machinery/vending/wardrobe/cargo_wardrobe,
-/obj/effect/turf_decal/tile/brown/half/contrasted{
- dir = 8
- },
-/obj/machinery/light/small/directional/west,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"jtA" = (
/obj/structure/table/glass,
/obj/effect/turf_decal/siding/white{
@@ -28302,6 +28257,13 @@
/obj/effect/mapping_helpers/airlock/access/all/service/crematorium,
/turf/open/floor/plating,
/area/station/maintenance/aft/greater)
+"khX" = (
+/obj/structure/reagent_dispensers/watertank,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"khZ" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/cable,
@@ -29617,13 +29579,6 @@
/obj/structure/window/reinforced/spawner/directional/west,
/turf/open/floor/engine,
/area/station/science/explab)
-"kHU" = (
-/obj/structure/reagent_dispensers/watertank,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"kIG" = (
/obj/structure/rack,
/obj/effect/spawner/random/maintenance/two,
@@ -32795,11 +32750,6 @@
/obj/vehicle/sealed/mecha/ripley/cargo,
/turf/open/floor/plating,
/area/station/cargo/warehouse)
-"lUe" = (
-/obj/structure/reagent_dispensers/fueltank,
-/obj/structure/sign/poster/contraband/random/directional/north,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"lUj" = (
/obj/structure/table,
/obj/item/book/manual/wiki/security_space_law{
@@ -33538,6 +33488,14 @@
},
/turf/open/floor/iron/white,
/area/station/medical/storage)
+"mhx" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/sorting/mail/flip{
+ dir = 1
+ },
+/obj/effect/mapping_helpers/mail_sorting/supply/disposals,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"mhA" = (
/obj/structure/cable,
/obj/machinery/power/apc/auto_name/directional/west,
@@ -34559,12 +34517,6 @@
/obj/structure/window/spawner/directional/south,
/turf/open/floor/iron/white,
/area/station/security/prison/mess)
-"mzs" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/mapping_helpers/broken_floor,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"mzu" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -34620,13 +34572,6 @@
/obj/machinery/light/small/directional/south,
/turf/open/floor/iron/dark,
/area/station/hallway/primary/port)
-"mAy" = (
-/obj/machinery/computer/order_console/mining,
-/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"mAJ" = (
/obj/effect/turf_decal/stripes/line,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -38013,6 +37958,15 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/station/commons/locker)
+"nFq" = (
+/obj/machinery/door/airlock/mining{
+ name = "Mining Office"
+ },
+/obj/structure/cable,
+/obj/machinery/door/firedoor,
+/obj/effect/mapping_helpers/airlock/access/all/supply/mining,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"nFL" = (
/obj/machinery/camera/directional/north{
c_tag = "MiniSat Exterior - Fore";
@@ -38316,6 +38270,18 @@
/obj/structure/flora/bush/flowers_br/style_random,
/turf/open/floor/grass,
/area/station/maintenance/starboard/aft)
+"nMk" = (
+/obj/machinery/door/airlock/mining{
+ name = "Mining Office"
+ },
+/obj/machinery/door/firedoor,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/disposalpipe/segment,
+/obj/effect/mapping_helpers/airlock/access/all/supply/mining,
+/obj/effect/landmark/navigate_destination,
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"nMz" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/table,
@@ -38331,13 +38297,6 @@
/obj/effect/turf_decal/tile/neutral/opposingcorners,
/turf/open/floor/iron,
/area/station/commons/vacant_room/commissary)
-"nME" = (
-/obj/structure/rack,
-/obj/effect/decal/cleanable/cobweb/cobweb2,
-/obj/item/storage/toolbox/emergency,
-/obj/effect/spawner/random/maintenance,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"nMF" = (
/obj/machinery/light/small/directional/east,
/obj/machinery/firealarm/directional/east,
@@ -40002,6 +39961,11 @@
"otu" = (
/turf/closed/wall,
/area/station/service/chapel)
+"oty" = (
+/obj/structure/chair/office/light,
+/obj/structure/cable,
+/turf/open/floor/iron/white,
+/area/station/command/heads_quarters/cmo)
"otG" = (
/obj/item/radio/intercom/directional/east,
/obj/structure/window/spawner/directional/north,
@@ -41003,6 +40967,15 @@
"oKU" = (
/turf/open/floor/circuit/green/telecomms/mainframe,
/area/station/tcommsat/server)
+"oLc" = (
+/obj/structure/disposalpipe/segment,
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"oLD" = (
/obj/structure/chair/comfy/beige,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -41100,6 +41073,11 @@
/obj/effect/turf_decal/tile/yellow/full,
/turf/open/floor/iron/white/smooth_large,
/area/station/medical/chemistry)
+"oNz" = (
+/obj/structure/cable,
+/obj/effect/landmark/event_spawn,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"oNP" = (
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
@@ -43380,6 +43358,14 @@
/obj/machinery/light/cold/directional/north,
/turf/open/floor/plating,
/area/station/security/prison/work)
+"pEZ" = (
+/obj/machinery/door/airlock/maintenance{
+ name = "Mining Dock Maintenance"
+ },
+/obj/structure/cable,
+/obj/effect/mapping_helpers/airlock/access/all/supply/mining,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"pFd" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -45121,11 +45107,6 @@
},
/turf/open/floor/iron/dark,
/area/station/command/bridge)
-"qlr" = (
-/obj/structure/cable,
-/obj/effect/landmark/event_spawn,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"qlG" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 1
@@ -46240,7 +46221,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 4
},
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/turf/open/floor/iron/dark/textured,
/area/station/medical/cryo)
"qIS" = (
@@ -46729,6 +46710,13 @@
/obj/structure/marker_beacon/indigo,
/turf/open/space/basic,
/area/space/nearstation)
+"qPt" = (
+/obj/effect/spawner/random/structure/crate,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"qPC" = (
/obj/structure/cable,
/obj/machinery/door/airlock/virology/glass{
@@ -46950,6 +46938,13 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/station/commons/storage/primary)
+"qSD" = (
+/obj/machinery/rnd/bepis,
+/obj/effect/turf_decal/stripes/end{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"qSP" = (
/obj/machinery/atmospherics/pipe/smart/manifold/purple/visible{
dir = 1
@@ -48053,6 +48048,13 @@
/obj/effect/turf_decal/tile/purple/opposingcorners,
/turf/open/floor/iron,
/area/station/science/research)
+"rnM" = (
+/obj/item/clothing/gloves/color/rainbow,
+/obj/item/clothing/shoes/sneakers/rainbow,
+/obj/item/clothing/under/color/rainbow,
+/obj/item/clothing/head/soft/rainbow,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"rnX" = (
/obj/machinery/suit_storage_unit/standard_unit,
/obj/machinery/firealarm/directional/east,
@@ -49531,13 +49533,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
-"rNV" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/disposalpipe/segment{
- dir = 6
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"rOz" = (
/obj/effect/spawner/random/structure/crate,
/turf/open/floor/plating,
@@ -49773,13 +49768,6 @@
},
/turf/open/floor/plating,
/area/station/service/chapel)
-"rSa" = (
-/obj/effect/decal/cleanable/blood/tracks{
- dir = 4
- },
-/obj/effect/spawner/random/structure/grille,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"rSi" = (
/obj/effect/landmark/start/chief_engineer,
/obj/structure/chair/office/light{
@@ -54072,13 +54060,6 @@
/obj/structure/cable,
/turf/open/floor/iron/cafeteria,
/area/station/service/kitchen)
-"ttG" = (
-/obj/item/clothing/gloves/color/rainbow,
-/obj/item/clothing/shoes/sneakers/rainbow,
-/obj/item/clothing/under/color/rainbow,
-/obj/item/clothing/head/soft/rainbow,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"ttM" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -57266,13 +57247,6 @@
/obj/effect/turf_decal/tile/red/half/contrasted,
/turf/open/floor/iron/dark,
/area/station/security/execution/education)
-"uyj" = (
-/obj/machinery/rnd/bepis,
-/obj/effect/turf_decal/stripes/end{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"uyr" = (
/obj/item/radio/intercom/directional/east,
/obj/structure/disposalpipe/segment,
@@ -58643,6 +58617,17 @@
/obj/effect/turf_decal/bot/left,
/turf/open/floor/engine,
/area/station/engineering/atmospherics_engine)
+"uWy" = (
+/obj/structure/table/glass,
+/obj/item/paper_bin,
+/obj/item/clipboard,
+/obj/item/toy/figure/cmo,
+/obj/structure/cable,
+/obj/item/stamp/head/cmo{
+ pixel_x = -9
+ },
+/turf/open/floor/iron/white,
+/area/station/command/heads_quarters/cmo)
"uWA" = (
/obj/structure/table/wood/fancy/royalblue,
/obj/machinery/door/window{
@@ -59760,13 +59745,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
-"vpU" = (
-/obj/effect/spawner/random/structure/crate,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"vpX" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -60517,6 +60495,13 @@
/obj/item/tail_pin,
/turf/open/space/basic,
/area/space/nearstation)
+"vDq" = (
+/obj/structure/closet/emcloset,
+/obj/structure/disposalpipe/segment{
+ dir = 5
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"vDt" = (
/obj/machinery/door/airlock/maintenance{
name = "Research Maintenance"
@@ -62258,6 +62243,13 @@
},
/turf/open/floor/iron,
/area/station/security/checkpoint/supply)
+"wfY" = (
+/obj/structure/rack,
+/obj/effect/decal/cleanable/cobweb/cobweb2,
+/obj/item/storage/toolbox/emergency,
+/obj/effect/spawner/random/maintenance,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"wfZ" = (
/obj/machinery/airalarm/directional/east,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -63745,7 +63737,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 8
},
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/turf/open/floor/iron/dark/textured,
/area/station/medical/cryo)
"wKu" = (
@@ -64856,15 +64848,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/white/side,
/area/station/science/lobby)
-"xdY" = (
-/obj/machinery/door/airlock/mining{
- name = "Mining Office"
- },
-/obj/structure/cable,
-/obj/machinery/door/firedoor,
-/obj/effect/mapping_helpers/airlock/access/all/supply/mining,
-/turf/open/floor/iron,
-/area/station/cargo/miningoffice)
"xel" = (
/obj/structure/closet/firecloset,
/turf/open/floor/plating,
@@ -65410,16 +65393,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/science/genetics)
-"xoc" = (
-/obj/machinery/door/airlock/maintenance{
- name = "Mining Dock Maintenance"
- },
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/disposalpipe/segment,
-/obj/effect/mapping_helpers/airlock/access/all/supply/mining,
-/turf/open/floor/plating,
-/area/station/maintenance/port/fore)
"xor" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/structure/cable,
@@ -65634,6 +65607,12 @@
},
/turf/open/floor/iron,
/area/station/commons/fitness/recreation)
+"xsQ" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/segment,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"xsV" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/poddoor/shutters/preopen{
@@ -66534,6 +66513,12 @@
},
/turf/open/floor/plating,
/area/station/maintenance/aft/greater)
+"xHQ" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"xIp" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/landmark/event_spawn,
@@ -66743,6 +66728,16 @@
/obj/structure/cable,
/turf/open/floor/wood,
/area/station/service/cafeteria)
+"xMP" = (
+/obj/machinery/door/airlock/maintenance{
+ name = "Mining Dock Maintenance"
+ },
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/segment,
+/obj/effect/mapping_helpers/airlock/access/all/supply/mining,
+/turf/open/floor/plating,
+/area/station/maintenance/port/fore)
"xMX" = (
/obj/effect/turf_decal/stripes/corner,
/obj/structure/cable,
@@ -66853,6 +66848,13 @@
},
/turf/open/floor/plating/airless,
/area/station/science/ordnance/bomb)
+"xOL" = (
+/obj/machinery/computer/order_console/mining,
+/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/cargo/miningoffice)
"xOO" = (
/obj/machinery/status_display/evac/directional/east,
/obj/structure/cable,
@@ -84975,8 +84977,8 @@ hxo
hxo
hxo
cbz
-uyj
-jty
+qSD
+iBx
jLb
tTa
kQP
@@ -85208,11 +85210,11 @@ gYE
lBm
qKy
ybN
-edP
-dwA
-bje
+oLc
+iPY
+vDq
jXu
-ttG
+rnM
jXu
pPh
aFd
@@ -85465,9 +85467,9 @@ iPE
vfv
cTQ
xte
-mzs
+izi
sHu
-kHU
+khX
jXu
jXu
jXu
@@ -85723,9 +85725,9 @@ uEC
wgw
twr
uuD
-qlr
-fBl
-eEb
+oNz
+iaA
+hNS
jXu
ouc
dSG
@@ -85733,7 +85735,7 @@ cLj
xYl
cLj
mUz
-xdY
+nFq
rgN
mmR
mmR
@@ -85978,19 +85980,19 @@ wvR
pQu
vEH
jXu
-lUe
+gjY
uuD
-rNV
-cGL
-guZ
-xoc
+dDR
+mhx
+xsQ
+xMP
xyz
xyz
kdC
btt
aqx
shx
-bGM
+nMk
fiC
dAk
rhn
@@ -86235,13 +86237,13 @@ vhU
eNU
aQE
jXu
-nME
+wfY
iUE
-gQv
+xHQ
jXu
jXu
jXu
-mAy
+xOL
cLj
kRe
aFd
@@ -86494,7 +86496,7 @@ jXu
jXu
jXu
uuD
-gQv
+xHQ
jXu
fhn
jXu
@@ -86751,12 +86753,12 @@ xxp
twr
sxn
uuD
-vpU
+qPt
twr
-rSa
+exq
jXu
jXu
-fNH
+pEZ
jXu
jXu
jXu
@@ -92217,8 +92219,8 @@ jhk
cOR
vgZ
ijZ
-bDS
-edo
+oty
+uWy
pXM
iNc
bqX
diff --git a/_maps/map_files/NSSJourney/NSSJourney.dmm b/_maps/map_files/NSSJourney/NSSJourney.dmm
index 19299f10006..bbe26804454 100644
--- a/_maps/map_files/NSSJourney/NSSJourney.dmm
+++ b/_maps/map_files/NSSJourney/NSSJourney.dmm
@@ -1472,6 +1472,7 @@
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/mapping_helpers/airlock/access/any/security/general,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/dark,
/area/station/security/brig)
"akV" = (
@@ -20993,7 +20994,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 6
},
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/turf/open/floor/iron/dark,
/area/station/medical/cryo)
"bBn" = (
@@ -21842,7 +21843,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 10
},
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/turf/open/floor/iron/dark,
/area/station/medical/cryo)
"bEc" = (
@@ -23065,6 +23066,13 @@
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/mapping_helpers/airlock/access/any/medical/virology,
+/obj/machinery/door_buttons/access_button{
+ idDoor = "virology_airlock_exterior";
+ idSelf = "virology_airlock_control";
+ name = "Virology Access Button";
+ req_access = list("virology");
+ pixel_x = -24
+ },
/turf/open/floor/iron,
/area/station/medical/virology)
"bHZ" = (
@@ -25275,6 +25283,14 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/mapping_helpers/airlock/access/any/medical/virology,
+/obj/machinery/door_buttons/access_button{
+ idDoor = "virology_airlock_interior";
+ idSelf = "virology_airlock_control";
+ name = "Virology Access Button";
+ pixel_x = -24;
+ req_access = list("virology");
+ pixel_y = 6
+ },
/turf/open/floor/iron,
/area/station/medical/virology)
"bQJ" = (
@@ -25549,13 +25565,14 @@
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 9
},
-/obj/machinery/door_buttons/access_button{
- idDoor = "virology_airlock_interior";
+/obj/machinery/door_buttons/airlock_controller{
+ idExterior = "virology_airlock_exterior";
+ idInterior = "virology_airlock_interior";
idSelf = "virology_airlock_control";
- name = "Virology Access Button";
- pixel_x = 8;
- req_access = list("virology");
- pixel_y = 24
+ name = "Virology Access Console";
+ pixel_x = 7;
+ pixel_y = 26;
+ req_access = list("virology")
},
/turf/open/floor/iron/white,
/area/station/medical/virology)
@@ -31870,7 +31887,7 @@
"cwy" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/table_frame,
-/obj/item/wirerod,
+/obj/item/melee/baton/security/cattleprod,
/obj/effect/spawner/random/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/starboard/aft)
@@ -37829,15 +37846,6 @@
dir = 10
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/door_buttons/airlock_controller{
- idExterior = "virology_airlock_exterior";
- idInterior = "virology_airlock_interior";
- idSelf = "virology_airlock_control";
- name = "Virology Access Console";
- pixel_x = 7;
- pixel_y = -26;
- req_access = list("virology")
- },
/turf/open/floor/iron/white,
/area/station/medical/virology)
"fSb" = (
@@ -58921,14 +58929,6 @@
dir = 10
},
/obj/item/kirbyplants/random,
-/obj/machinery/door_buttons/access_button{
- idDoor = "virology_airlock_exterior";
- idSelf = "virology_airlock_control";
- name = "Virology Access Button";
- req_access = list("virology");
- pixel_y = -24;
- pixel_x = 8
- },
/turf/open/floor/iron/white,
/area/station/medical/medbay/aft)
"yck" = (
diff --git a/_maps/map_files/NorthStar/north_star.dmm b/_maps/map_files/NorthStar/north_star.dmm
index d9fff1d8af0..53e9e0a8d54 100644
--- a/_maps/map_files/NorthStar/north_star.dmm
+++ b/_maps/map_files/NorthStar/north_star.dmm
@@ -318,6 +318,12 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/catwalk_floor/iron_dark,
/area/station/maintenance/floor2/port)
+"ads" = (
+/obj/effect/turf_decal/stripes{
+ dir = 9
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/floor1/starboard/fore)
"adB" = (
/obj/structure/closet/crate/bin{
name = "biowaste bin"
@@ -1730,6 +1736,22 @@
/obj/machinery/light/small/directional/west,
/turf/open/floor/wood,
/area/station/medical/psychology)
+"avu" = (
+/obj/effect/turf_decal/siding/thinplating_new/dark{
+ dir = 4
+ },
+/obj/machinery/door/airlock/hatch{
+ name = "Maintenance Access"
+ },
+/obj/effect/mapping_helpers/airlock/access/any/supply/general,
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/pod/dark,
+/area/station/maintenance/floor1/starboard/fore)
"avH" = (
/obj/structure/table/glass,
/obj/item/experi_scanner,
@@ -2975,6 +2997,13 @@
},
/turf/open/floor/iron/dark/textured,
/area/station/commons/fitness)
+"aOv" = (
+/obj/effect/turf_decal/stripes{
+ dir = 10
+ },
+/obj/effect/mapping_helpers/broken_floor,
+/turf/open/floor/plating,
+/area/station/maintenance/floor1/starboard/fore)
"aOx" = (
/obj/machinery/griddle,
/obj/machinery/airalarm/directional/west,
@@ -3463,6 +3492,11 @@
/obj/effect/mapping_helpers/airlock/access/any/medical/psychology,
/turf/open/floor/catwalk_floor,
/area/station/hallway/floor2/fore)
+"aUn" = (
+/obj/effect/spawner/random/structure/table_or_rack,
+/obj/effect/spawner/random/trash/soap,
+/turf/open/floor/pod/light,
+/area/station/maintenance/floor1/starboard/fore)
"aUG" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/spawner/random/structure/table_or_rack,
@@ -3716,6 +3750,12 @@
/obj/machinery/light/small/directional/east,
/turf/open/floor/carpet/purple,
/area/station/maintenance/floor1/port/aft)
+"aXl" = (
+/obj/machinery/cryo_cell{
+ dir = 4
+ },
+/turf/open/floor/iron/dark/textured,
+/area/station/medical/cryo)
"aXq" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -5398,6 +5438,18 @@
/obj/machinery/light/small/directional/east,
/turf/open/floor/iron/white,
/area/station/science/xenobiology/hallway)
+"bqm" = (
+/obj/machinery/door/firedoor/border_only{
+ dir = 1
+ },
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/disposalpipe/segment{
+ dir = 5
+ },
+/turf/open/floor/catwalk_floor,
+/area/station/maintenance/floor1/starboard/fore)
"bqn" = (
/obj/structure/closet/crate,
/obj/item/reagent_containers/cup/bowl,
@@ -5544,13 +5596,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/white,
/area/station/science/robotics/lab)
-"brL" = (
-/obj/effect/turf_decal/stripes{
- dir = 6
- },
-/obj/structure/disposalpipe/segment,
-/turf/open/floor/plating,
-/area/station/maintenance/floor1/starboard/fore)
"brN" = (
/obj/effect/spawner/structure/window/hollow/reinforced/directional,
/obj/structure/disposalpipe/segment,
@@ -5571,10 +5616,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/medical/abandoned)
-"bsq" = (
-/obj/effect/turf_decal/stripes,
-/turf/open/floor/plating,
-/area/station/maintenance/floor1/starboard/fore)
"bsu" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
@@ -6346,15 +6387,6 @@
dir = 4
},
/area/station/hallway/floor3/aft)
-"bAh" = (
-/obj/machinery/door/firedoor/border_only{
- dir = 1
- },
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/catwalk_floor,
-/area/station/maintenance/floor1/starboard/fore)
"bAj" = (
/obj/machinery/conveyor{
dir = 9;
@@ -8910,6 +8942,14 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/smooth,
/area/station/construction)
+"cjz" = (
+/obj/machinery/door/firedoor/border_only{
+ dir = 8
+ },
+/obj/machinery/firealarm/directional/east,
+/obj/machinery/firealarm/directional/east,
+/turf/open/floor/pod/light,
+/area/station/maintenance/floor1/starboard/fore)
"cjB" = (
/obj/effect/turf_decal/stripes/line,
/obj/effect/decal/cleanable/dirt,
@@ -9963,6 +10003,17 @@
},
/turf/open/floor/engine,
/area/station/engineering/atmos/hfr_room)
+"cxp" = (
+/obj/machinery/exoscanner,
+/obj/effect/turf_decal/stripes{
+ dir = 1
+ },
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 1
+ },
+/obj/structure/extinguisher_cabinet/directional/west,
+/turf/open/floor/iron/corner,
+/area/station/cargo/drone_bay)
"cxx" = (
/obj/effect/turf_decal/tile/green/half{
dir = 4
@@ -10205,14 +10256,6 @@
},
/turf/open/floor/engine/vacuum,
/area/station/science/ordnance/freezerchamber)
-"cBT" = (
-/obj/machinery/door/firedoor/border_only{
- dir = 8
- },
-/obj/machinery/firealarm/directional/east,
-/obj/machinery/firealarm/directional/east,
-/turf/open/floor/pod/light,
-/area/station/maintenance/floor1/starboard/fore)
"cBU" = (
/obj/structure/window/reinforced/spawner/directional/west,
/obj/structure/flora/bush/sunny/style_random,
@@ -10321,12 +10364,6 @@
/obj/machinery/chem_master,
/turf/open/floor/iron/dark/textured,
/area/station/medical/pharmacy)
-"cDe" = (
-/obj/effect/turf_decal/stripes{
- dir = 1
- },
-/turf/open/floor/plating,
-/area/station/maintenance/floor1/starboard/fore)
"cDh" = (
/obj/item/broken_bottle,
/turf/open/floor/carpet/neon/simple/pink/nodots,
@@ -13156,7 +13193,7 @@
/area/station/maintenance/floor3/port/fore)
"dss" = (
/obj/effect/mapping_helpers/broken_floor,
-/obj/item/wirerod,
+/obj/item/melee/baton/security/cattleprod,
/turf/open/floor/plating,
/area/station/maintenance/floor1/port/aft)
"dsv" = (
@@ -14644,6 +14681,15 @@
/obj/effect/landmark/start/captain,
/turf/open/floor/wood/tile,
/area/station/command/heads_quarters/captain/private)
+"dNf" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/catwalk_floor,
+/area/station/maintenance/floor1/starboard/fore)
"dNm" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 1
@@ -15498,6 +15544,10 @@
dir = 4
},
/area/station/hallway/floor2/fore)
+"dXP" = (
+/obj/machinery/computer/exodrone_control_console,
+/turf/open/floor/iron/dark,
+/area/station/cargo/drone_bay)
"dXX" = (
/obj/structure/window/reinforced/spawner/directional/west,
/obj/machinery/rnd/production/techfab/department/security,
@@ -15533,6 +15583,19 @@
/obj/machinery/light/small/directional/east,
/turf/open/floor/iron,
/area/station/engineering/atmos/project)
+"dYm" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes{
+ dir = 4
+ },
+/obj/structure/disposalpipe/segment{
+ dir = 10
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"dYq" = (
/obj/structure/reagent_dispensers/watertank,
/obj/effect/turf_decal/stripes{
@@ -16782,21 +16845,6 @@
/obj/machinery/duct,
/turf/open/floor/iron/showroomfloor,
/area/station/commons/toilet)
-"eoo" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/stripes/corner{
- dir = 4
- },
-/obj/structure/disposalpipe/segment{
- dir = 5
- },
-/obj/structure/railing/corner/end{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"eop" = (
/obj/structure/disposalpipe/segment{
dir = 6
@@ -16970,18 +17018,6 @@
/obj/structure/cable,
/turf/open/floor/catwalk_floor,
/area/station/maintenance/floor1/starboard)
-"erV" = (
-/obj/machinery/door/firedoor/border_only{
- dir = 1
- },
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/disposalpipe/segment{
- dir = 5
- },
-/turf/open/floor/catwalk_floor,
-/area/station/maintenance/floor1/starboard/fore)
"erY" = (
/obj/machinery/vending/wardrobe/bar_wardrobe,
/turf/open/floor/wood,
@@ -17112,12 +17148,6 @@
},
/turf/open/floor/pod/dark,
/area/station/maintenance/floor3/starboard)
-"eul" = (
-/obj/effect/turf_decal/stripes{
- dir = 8
- },
-/turf/open/floor/plating,
-/area/station/maintenance/floor1/starboard/fore)
"euu" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
@@ -18527,6 +18557,10 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/turf/open/floor/wood/tile,
/area/station/service/library)
+"ePI" = (
+/obj/effect/turf_decal/stripes,
+/turf/open/floor/plating,
+/area/station/maintenance/floor1/starboard/fore)
"ePJ" = (
/obj/effect/turf_decal/trimline/red/line{
dir = 1
@@ -18750,6 +18784,11 @@
/obj/machinery/newscaster/directional/west,
/turf/open/floor/wood,
/area/station/hallway/secondary/entry)
+"eTD" = (
+/obj/effect/turf_decal/bot,
+/obj/structure/sign/poster/random/directional/north,
+/turf/open/floor/iron/smooth,
+/area/station/cargo/warehouse)
"eTH" = (
/obj/structure/flora/bush/sparsegrass/style_random,
/mob/living/carbon/human/species/monkey,
@@ -20930,6 +20969,12 @@
dir = 1
},
/area/station/command/bridge)
+"fBB" = (
+/obj/effect/turf_decal/stripes{
+ dir = 5
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/floor1/starboard/fore)
"fBM" = (
/obj/effect/turf_decal/delivery,
/turf/open/floor/iron/dark,
@@ -20969,13 +21014,6 @@
"fCp" = (
/turf/open/floor/plating/airless,
/area/space)
-"fCw" = (
-/obj/effect/turf_decal/stripes{
- dir = 4
- },
-/obj/structure/disposalpipe/trunk/multiz,
-/turf/open/floor/plating,
-/area/station/maintenance/floor1/starboard/fore)
"fCx" = (
/obj/structure/rack,
/turf/open/floor/pod/dark,
@@ -23103,6 +23141,11 @@
/obj/machinery/light/small/directional/east,
/turf/open/floor/wood/tile,
/area/station/service/library)
+"gex" = (
+/obj/structure/rack,
+/obj/effect/spawner/random/maintenance/two,
+/turf/open/floor/pod/light,
+/area/station/maintenance/floor1/starboard/fore)
"geA" = (
/obj/effect/turf_decal/tile/blue/opposingcorners,
/obj/item/kirbyplants/random,
@@ -24078,17 +24121,6 @@
/obj/structure/chair/stool/bar/directional/east,
/turf/open/floor/iron/white,
/area/station/science/circuits)
-"gso" = (
-/obj/structure/railing{
- dir = 4
- },
-/obj/effect/turf_decal/stripes{
- dir = 4
- },
-/obj/structure/disposalpipe/segment,
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"gsp" = (
/obj/machinery/door/airlock/medical{
id_tag = "asylum_airlock_exterior";
@@ -24311,6 +24343,10 @@
},
/turf/open/floor/iron/dark/textured,
/area/station/medical/medbay/lobby)
+"gvu" = (
+/obj/effect/spawner/random/structure/crate,
+/turf/open/floor/pod/light,
+/area/station/maintenance/floor1/starboard/fore)
"gvx" = (
/obj/effect/turf_decal/trimline/blue/filled/corner,
/turf/open/floor/iron/white,
@@ -24856,6 +24892,12 @@
/obj/structure/extinguisher_cabinet/directional/west,
/turf/open/floor/iron/white,
/area/station/medical/medbay/lobby)
+"gCn" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/light/broken/directional/north,
+/obj/item/radio/intercom/directional/north,
+/turf/open/floor/catwalk_floor/iron_smooth,
+/area/station/cargo/warehouse)
"gCv" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -25096,10 +25138,6 @@
/obj/machinery/door/firedoor/border_only,
/turf/open/floor/pod/dark,
/area/station/maintenance/floor2/starboard/aft)
-"gFU" = (
-/obj/machinery/computer/exodrone_control_console,
-/turf/open/floor/iron/dark,
-/area/station/cargo/drone_bay)
"gGe" = (
/obj/machinery/telecomms/bus/preset_one,
/turf/open/floor/circuit/telecomms,
@@ -28054,10 +28092,6 @@
},
/turf/open/floor/pod/dark,
/area/station/maintenance/floor2/port/fore)
-"htK" = (
-/obj/effect/spawner/random/maintenance,
-/turf/open/floor/pod/light,
-/area/station/maintenance/floor1/starboard/fore)
"htW" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/catwalk_floor/iron,
@@ -28653,12 +28687,6 @@
/obj/effect/spawner/random/maintenance,
/turf/open/floor/pod/light,
/area/station/maintenance/floor2/port/aft)
-"hBR" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/machinery/light/broken/directional/north,
-/obj/item/radio/intercom/directional/north,
-/turf/open/floor/catwalk_floor/iron_smooth,
-/area/station/cargo/warehouse)
"hBT" = (
/obj/structure/table,
/obj/structure/bedsheetbin,
@@ -30476,11 +30504,6 @@
},
/turf/open/floor/iron/dark,
/area/station/commons/dorms/room4)
-"iaJ" = (
-/obj/structure/rack,
-/obj/effect/spawner/random/maintenance/two,
-/turf/open/floor/pod/light,
-/area/station/maintenance/floor1/starboard/fore)
"iaO" = (
/obj/structure/rack,
/obj/structure/sign/nanotrasen{
@@ -30573,6 +30596,10 @@
dir = 4
},
/area/station/commons/storage/primary)
+"icf" = (
+/obj/effect/spawner/random/maintenance,
+/turf/open/floor/pod/light,
+/area/station/maintenance/floor1/starboard/fore)
"ick" = (
/obj/effect/turf_decal/trimline/brown/warning{
dir = 8
@@ -31457,17 +31484,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/white,
/area/station/medical/medbay/lobby)
-"ioi" = (
-/obj/machinery/exoscanner,
-/obj/effect/turf_decal/stripes{
- dir = 1
- },
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
- dir = 1
- },
-/obj/structure/extinguisher_cabinet/directional/west,
-/turf/open/floor/iron/corner,
-/area/station/cargo/drone_bay)
"iom" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -32662,13 +32678,6 @@
/obj/machinery/firealarm/directional/east,
/turf/open/floor/catwalk_floor,
/area/station/maintenance/floor3/starboard/fore)
-"iDJ" = (
-/obj/effect/turf_decal/stripes{
- dir = 10
- },
-/obj/effect/mapping_helpers/broken_floor,
-/turf/open/floor/plating,
-/area/station/maintenance/floor1/starboard/fore)
"iDP" = (
/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plating,
@@ -33353,6 +33362,12 @@
/obj/effect/mapping_helpers/mail_sorting/service/bar,
/turf/open/floor/iron/dark/side,
/area/station/hallway/floor3/fore)
+"iOl" = (
+/obj/machinery/modular_computer/preset/civilian,
+/obj/machinery/power/apc/auto_name/directional/north,
+/obj/structure/cable,
+/turf/open/floor/iron/dark,
+/area/station/cargo/drone_bay)
"iOp" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -34786,10 +34801,6 @@
/obj/structure/cable,
/turf/open/floor/pod/light,
/area/station/maintenance/floor1/starboard/fore)
-"jhP" = (
-/obj/effect/spawner/random/structure/crate,
-/turf/open/floor/pod/light,
-/area/station/maintenance/floor1/starboard/fore)
"jhU" = (
/turf/open/floor/iron/white,
/area/station/science/robotics/lab)
@@ -36139,19 +36150,6 @@
},
/turf/open/floor/carpet/royalblack,
/area/station/service/kitchen/diner)
-"jAr" = (
-/obj/structure/railing{
- dir = 4
- },
-/obj/effect/turf_decal/stripes{
- dir = 4
- },
-/obj/structure/disposalpipe/segment,
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"jAB" = (
/obj/machinery/light/floor,
/turf/open/floor/iron/dark/side{
@@ -37741,10 +37739,6 @@
/obj/effect/turf_decal/trimline/purple/warning,
/turf/open/floor/iron/dark,
/area/station/hallway/floor2/fore)
-"jWJ" = (
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"jWR" = (
/obj/structure/railing/corner,
/obj/effect/turf_decal/siding/wood/corner{
@@ -41274,6 +41268,19 @@
/obj/effect/spawner/random/engineering/flashlight,
/turf/open/floor/pod/light,
/area/station/maintenance/floor2/port/aft)
+"kQL" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes{
+ dir = 4
+ },
+/obj/structure/disposalpipe/segment,
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"kQN" = (
/obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -41905,6 +41912,13 @@
/obj/structure/rack,
/turf/open/floor/pod/light,
/area/station/maintenance/floor2/port/fore)
+"kYs" = (
+/obj/effect/turf_decal/stripes{
+ dir = 4
+ },
+/obj/structure/disposalpipe/trunk/multiz,
+/turf/open/floor/plating,
+/area/station/maintenance/floor1/starboard/fore)
"kYt" = (
/obj/structure/chair/comfy/carp,
/turf/open/floor/carpet/neon/simple/pink/nodots,
@@ -42564,12 +42578,6 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/commons/fitness/recreation)
-"lgs" = (
-/obj/effect/turf_decal/stripes{
- dir = 5
- },
-/turf/open/floor/plating,
-/area/station/maintenance/floor1/starboard/fore)
"lgv" = (
/obj/structure/rack,
/obj/item/book/manual/nuclear,
@@ -43940,6 +43948,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/checker,
/area/station/cargo/miningdock)
+"lAv" = (
+/obj/machinery/cryo_cell{
+ dir = 8
+ },
+/obj/structure/sign/poster/official/random/directional/east,
+/turf/open/floor/iron/dark/textured,
+/area/station/medical/cryo)
"lAD" = (
/obj/effect/turf_decal/trimline/green/filled/arrow_cw{
dir = 10
@@ -44578,6 +44593,12 @@
/obj/structure/reagent_dispensers/fueltank,
/turf/open/floor/pod/light,
/area/station/maintenance/floor1/port)
+"lJl" = (
+/obj/machinery/door/firedoor/border_only{
+ dir = 8
+ },
+/turf/open/floor/pod/light,
+/area/station/maintenance/floor1/starboard/fore)
"lJn" = (
/obj/item/radio/intercom/directional/west,
/turf/open/floor/iron/dark/side{
@@ -48391,6 +48412,18 @@
/obj/effect/landmark/start/assistant,
/turf/open/floor/carpet/red,
/area/station/commons/dorms/apartment1)
+"mFK" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/cable,
+/obj/effect/turf_decal/stripes{
+ dir = 4
+ },
+/obj/structure/railing{
+ dir = 4
+ },
+/obj/structure/disposalpipe/segment,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"mFP" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -50121,6 +50154,17 @@
},
/turf/open/floor/iron/white/herringbone,
/area/station/medical/patients_rooms)
+"ncf" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes{
+ dir = 4
+ },
+/obj/structure/disposalpipe/segment,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"ncl" = (
/obj/structure/dresser,
/turf/open/floor/carpet/red,
@@ -50884,22 +50928,6 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/dark,
/area/station/hallway/floor3/aft)
-"nkT" = (
-/obj/effect/turf_decal/siding/thinplating_new/dark{
- dir = 4
- },
-/obj/machinery/door/airlock/hatch{
- name = "Maintenance Access"
- },
-/obj/effect/mapping_helpers/airlock/access/any/supply/general,
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/pod/dark,
-/area/station/maintenance/floor1/starboard/fore)
"nla" = (
/obj/structure/table/wood,
/obj/effect/turf_decal/siding/wood{
@@ -55540,15 +55568,6 @@
},
/turf/open/floor/iron/dark/side,
/area/station/security/checkpoint)
-"owk" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/catwalk_floor,
-/area/station/maintenance/floor1/starboard/fore)
"owo" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable,
@@ -55825,6 +55844,15 @@
/obj/effect/spawner/random/structure/closet_maintenance,
/turf/open/floor/pod/dark,
/area/station/maintenance/floor3/port/aft)
+"ozY" = (
+/obj/machinery/door/firedoor/border_only{
+ dir = 1
+ },
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/catwalk_floor,
+/area/station/maintenance/floor1/starboard/fore)
"oAc" = (
/obj/effect/turf_decal/trimline/purple/line,
/obj/machinery/door/firedoor/border_only{
@@ -58866,17 +58894,6 @@
/obj/effect/decal/cleanable/blood/drip,
/turf/open/misc/dirt/jungle,
/area/station/service/hydroponics/garden/abandoned)
-"prm" = (
-/obj/structure/railing{
- dir = 4
- },
-/obj/effect/turf_decal/stripes{
- dir = 4
- },
-/obj/structure/disposalpipe/segment,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"pro" = (
/obj/effect/turf_decal/stripes,
/obj/effect/decal/cleanable/dirt,
@@ -59739,12 +59756,6 @@
/obj/effect/turf_decal/trimline/green/filled/line,
/turf/open/floor/iron/dark,
/area/station/medical/virology)
-"pCW" = (
-/obj/effect/decal/cleanable/cobweb/cobweb2,
-/obj/machinery/rnd/bepis,
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron,
-/area/station/cargo/warehouse)
"pDd" = (
/obj/structure/table/reinforced/plasmarglass,
/obj/item/reagent_containers/pill/epinephrine{
@@ -64285,18 +64296,6 @@
/obj/machinery/light_switch/directional/east,
/turf/open/floor/iron/dark,
/area/station/command/bridge)
-"qOr" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/cable,
-/obj/effect/turf_decal/stripes{
- dir = 4
- },
-/obj/structure/railing{
- dir = 4
- },
-/obj/structure/disposalpipe/segment,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"qOs" = (
/obj/structure/table/wood/fancy/red,
/obj/item/paper_bin,
@@ -66019,12 +66018,6 @@
},
/turf/open/floor/iron/dark,
/area/station/medical/psychology)
-"rku" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell{
- dir = 4
- },
-/turf/open/floor/iron/dark/textured,
-/area/station/medical/cryo)
"rkE" = (
/obj/structure/disposalpipe/trunk/multiz{
dir = 1
@@ -66480,19 +66473,6 @@
/obj/machinery/duct,
/turf/open/floor/iron/dark/textured,
/area/station/medical/cryo)
-"rqB" = (
-/obj/structure/railing{
- dir = 4
- },
-/obj/effect/turf_decal/stripes{
- dir = 4
- },
-/obj/structure/disposalpipe/segment{
- dir = 10
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"rqK" = (
/obj/effect/turf_decal/stripes/full,
/obj/structure/window/reinforced/spawner/directional/west,
@@ -67511,11 +67491,6 @@
},
/turf/open/floor/plating,
/area/station/medical/abandoned)
-"rGF" = (
-/obj/effect/turf_decal/bot,
-/obj/structure/sign/poster/random/directional/north,
-/turf/open/floor/iron/smooth,
-/area/station/cargo/warehouse)
"rGI" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -69902,15 +69877,6 @@
/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/station/hallway/floor4/aft)
-"sqK" = (
-/obj/structure/railing{
- dir = 4
- },
-/obj/effect/turf_decal/stripes{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"srz" = (
/obj/machinery/door/airlock/atmos{
name = "Atmospherics"
@@ -71466,12 +71432,6 @@
/obj/structure/sign/warning/xeno_mining/directional/north,
/turf/open/floor/iron/white,
/area/station/science/xenobiology/hallway)
-"sLq" = (
-/obj/machinery/door/firedoor/border_only{
- dir = 8
- },
-/turf/open/floor/pod/light,
-/area/station/maintenance/floor1/starboard/fore)
"sLE" = (
/obj/machinery/door/airlock/security/glass{
name = "Security Entrance"
@@ -75480,6 +75440,13 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/textured_large,
/area/station/engineering/lobby)
+"tNh" = (
+/obj/effect/turf_decal/stripes{
+ dir = 6
+ },
+/obj/structure/disposalpipe/segment,
+/turf/open/floor/plating,
+/area/station/maintenance/floor1/starboard/fore)
"tNi" = (
/obj/structure/table/wood,
/obj/effect/spawner/random/entertainment/cigar,
@@ -76114,6 +76081,15 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/dark,
/area/station/service/chapel/funeral)
+"tWc" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"tWn" = (
/obj/machinery/portable_atmospherics/canister/oxygen,
/obj/effect/turf_decal/bot,
@@ -78136,6 +78112,12 @@
/obj/structure/closet,
/turf/open/floor/pod/light,
/area/station/maintenance/floor2/port/fore)
+"uzr" = (
+/obj/effect/turf_decal/stripes{
+ dir = 1
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/floor1/starboard/fore)
"uzB" = (
/obj/structure/table/reinforced,
/obj/item/screwdriver,
@@ -78372,11 +78354,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/floor2/aft)
-"uDm" = (
-/obj/effect/spawner/random/structure/table_or_rack,
-/obj/effect/spawner/random/trash/soap,
-/turf/open/floor/pod/light,
-/area/station/maintenance/floor1/starboard/fore)
"uDr" = (
/obj/machinery/light/small/directional/north,
/obj/effect/decal/cleanable/dirt,
@@ -79853,6 +79830,12 @@
/obj/machinery/light/small/directional/north,
/turf/open/floor/iron/dark/smooth_large,
/area/station/science/robotics/lab)
+"uVb" = (
+/obj/effect/turf_decal/stripes{
+ dir = 8
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/floor1/starboard/fore)
"uVh" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -82160,6 +82143,10 @@
/obj/effect/turf_decal/trimline/brown/arrow_ccw,
/turf/open/floor/iron/dark/side,
/area/station/cargo/lobby)
+"vzo" = (
+/obj/structure/cable,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"vzu" = (
/obj/effect/landmark/start/psychologist,
/obj/structure/sign/poster/official/random/directional/south,
@@ -83302,6 +83289,17 @@
/obj/machinery/atmospherics/pipe/heat_exchanging/simple/layer2,
/turf/open/floor/engine/vacuum,
/area/station/science/ordnance/freezerchamber)
+"vPU" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes{
+ dir = 4
+ },
+/obj/structure/disposalpipe/segment,
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"vQb" = (
/obj/effect/turf_decal/siding/wood{
dir = 6
@@ -84079,13 +84077,6 @@
/obj/machinery/firealarm/directional/west,
/turf/open/floor/iron,
/area/station/hallway/floor2/aft)
-"waA" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell{
- dir = 8
- },
-/obj/structure/sign/poster/official/random/directional/east,
-/turf/open/floor/iron/dark/textured,
-/area/station/medical/cryo)
"waI" = (
/obj/effect/turf_decal/stripes,
/obj/machinery/atmospherics/components/binary/pump/off{
@@ -84655,12 +84646,6 @@
/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/station/hallway/floor4/aft)
-"whN" = (
-/obj/effect/turf_decal/stripes{
- dir = 9
- },
-/turf/open/floor/plating,
-/area/station/maintenance/floor1/starboard/fore)
"whR" = (
/turf/closed/wall,
/area/station/service/bar)
@@ -85722,6 +85707,21 @@
},
/turf/open/floor/iron,
/area/station/hallway/secondary/service)
+"wuE" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/stripes/corner{
+ dir = 4
+ },
+/obj/structure/disposalpipe/segment{
+ dir = 5
+ },
+/obj/structure/railing/corner/end{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"wuJ" = (
/obj/effect/turf_decal/tile/dark_red/fourcorners,
/turf/open/floor/iron,
@@ -89286,6 +89286,12 @@
"xpI" = (
/turf/closed/wall,
/area/station/maintenance/solars/starboard/fore)
+"xpK" = (
+/obj/effect/decal/cleanable/cobweb/cobweb2,
+/obj/machinery/rnd/bepis,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/iron,
+/area/station/cargo/warehouse)
"xpL" = (
/obj/machinery/door/airlock/research/glass/incinerator/ordmix_exterior{
name = "Burn Chamber Exterior Airlock"
@@ -91152,12 +91158,6 @@
/obj/structure/cable,
/turf/open/floor/catwalk_floor,
/area/station/maintenance/floor2/starboard/fore)
-"xOd" = (
-/obj/machinery/modular_computer/preset/civilian,
-/obj/machinery/power/apc/auto_name/directional/north,
-/obj/structure/cable,
-/turf/open/floor/iron/dark,
-/area/station/cargo/drone_bay)
"xOe" = (
/obj/machinery/light/cold/no_nightlight/directional/north,
/turf/open/floor/engine,
@@ -115258,10 +115258,10 @@ owI
owI
oic
oic
-whN
-eul
-iDJ
-bAh
+ads
+uVb
+aOv
+ozY
oic
oic
oic
@@ -115515,11 +115515,11 @@ owI
owI
oic
oic
-cDe
+uzr
oic
-bsq
-bAh
-htK
+ePI
+ozY
+icf
oic
gUS
nOj
@@ -115772,13 +115772,13 @@ owI
owI
oic
oic
-lgs
-fCw
-brL
-erV
-uDm
+fBB
+kYs
+tNh
+bqm
+aUn
oic
-rGF
+eTD
yiZ
yiZ
bUC
@@ -116029,13 +116029,13 @@ owI
owI
oic
oic
-sLq
-sLq
-cBT
-owk
-jhP
+lJl
+lJl
+cjz
+dNf
+gvu
oic
-hBR
+gCn
qWJ
qWJ
imO
@@ -116286,10 +116286,10 @@ owI
owI
oic
oic
-iaJ
+gex
oic
oic
-nkT
+avu
oic
oic
rYA
@@ -116545,9 +116545,9 @@ oic
oic
oic
oic
-xOd
+iOl
xxQ
-ioi
+cxp
aQK
fve
fve
@@ -116802,7 +116802,7 @@ uYl
pFb
gHw
yef
-gFU
+dXP
kHQ
hIj
aQK
@@ -117063,7 +117063,7 @@ wZu
vTt
hai
aQK
-pCW
+xpK
rhs
eaW
lSJ
@@ -117578,7 +117578,7 @@ fuJ
aQK
aQK
cfO
-jWJ
+vzo
mnR
mnk
mnR
@@ -117830,13 +117830,13 @@ cUL
cUL
oKT
xsL
-sqK
-rqB
-prm
-jAr
-gso
-qOr
-eoo
+tWc
+dYm
+ncf
+kQL
+vPU
+mFK
+wuE
myW
myW
myW
@@ -194971,7 +194971,7 @@ gHO
yba
lfW
wdd
-rku
+aXl
nqM
qQM
dHR
@@ -196513,7 +196513,7 @@ dXy
bND
aHK
wdd
-waA
+lAv
wat
mVm
tfX
diff --git a/_maps/map_files/VoidRaptor/VoidRaptor.dmm b/_maps/map_files/VoidRaptor/VoidRaptor.dmm
index c3918c21108..a68a80d0d40 100644
--- a/_maps/map_files/VoidRaptor/VoidRaptor.dmm
+++ b/_maps/map_files/VoidRaptor/VoidRaptor.dmm
@@ -14574,7 +14574,7 @@
},
/area/station/cargo/lobby)
"ejt" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/obj/effect/turf_decal/bot,
/obj/effect/turf_decal/tile/dark_blue/fourcorners,
/turf/open/floor/iron/dark,
@@ -20502,7 +20502,7 @@
/turf/closed/wall/r_wall,
/area/station/engineering/atmos/storage/gas)
"fXS" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/obj/effect/turf_decal/bot,
/obj/structure/disposalpipe/segment,
/obj/effect/turf_decal/tile/dark_blue/fourcorners,
diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm
index 4ef52187a09..ac5d9ba0e1d 100644
--- a/_maps/map_files/tramstation/tramstation.dmm
+++ b/_maps/map_files/tramstation/tramstation.dmm
@@ -451,19 +451,6 @@
"abM" = (
/turf/open/misc/asteroid,
/area/station/asteroid)
-"abN" = (
-/obj/effect/turf_decal/delivery,
-/obj/machinery/navbeacon{
- codes_txt = "delivery;dir=1";
- location = "QM #6"
- },
-/obj/effect/turf_decal/tile/brown/fourcorners,
-/mob/living/simple_animal/bot/mulebot{
- home_destination = "QM #6";
- suffix = "#6"
- },
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"abO" = (
/obj/structure/disposalpipe/segment,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -3861,12 +3848,6 @@
/obj/effect/turf_decal/trimline/neutral/warning,
/turf/open/floor/iron/dark,
/area/station/medical/morgue)
-"axF" = (
-/obj/effect/turf_decal/trimline/brown/filled/line{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"axG" = (
/obj/effect/turf_decal/bot,
/obj/effect/spawner/random/structure/crate_empty,
@@ -6213,6 +6194,13 @@
},
/turf/open/floor/iron,
/area/station/maintenance/tram/mid)
+"aVM" = (
+/obj/effect/turf_decal/trimline/brown/filled/line{
+ dir = 1
+ },
+/obj/effect/turf_decal/trimline/brown/filled/line,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"aVT" = (
/obj/effect/turf_decal/stripes/line,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -6250,6 +6238,24 @@
/obj/machinery/suit_storage_unit/industrial/loader,
/turf/open/floor/iron,
/area/station/cargo/warehouse)
+"aWQ" = (
+/obj/effect/turf_decal/trimline/brown/filled/corner{
+ dir = 8
+ },
+/obj/effect/turf_decal/trimline/brown/filled/corner{
+ dir = 1
+ },
+/obj/effect/turf_decal/siding/thinplating{
+ dir = 1
+ },
+/obj/effect/turf_decal/loading_area{
+ dir = 1
+ },
+/obj/effect/turf_decal/stripes/corner{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"aWY" = (
/obj/structure/stairs/west,
/turf/open/floor/iron/stairs/right{
@@ -6356,6 +6362,11 @@
},
/turf/open/floor/iron,
/area/station/cargo/storage)
+"aZT" = (
+/obj/effect/landmark/event_spawn,
+/obj/structure/cable,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"aZX" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
dir = 1
@@ -10091,15 +10102,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/cafeteria,
/area/station/command/heads_quarters/rd)
-"csn" = (
-/obj/machinery/elevator_control_panel{
- layer = 3.1;
- linked_elevator_id = "tram_xeno_lift";
- pixel_y = 2;
- preset_destination_names = list("2"="Lower Deck","3"="Upper Deck")
- },
-/turf/closed/wall,
-/area/station/science/xenobiology)
"csA" = (
/turf/closed/wall,
/area/station/solars/starboard/fore)
@@ -10722,12 +10724,6 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/engineering/atmos)
-"cEy" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell{
- dir = 4
- },
-/turf/open/floor/iron/dark,
-/area/station/medical/treatment_center)
"cEA" = (
/obj/effect/turf_decal/trimline/purple/filled/line,
/obj/machinery/firealarm/directional/south,
@@ -13466,6 +13462,12 @@
/obj/machinery/light/directional/south,
/turf/open/floor/iron,
/area/station/security/prison)
+"dCY" = (
+/obj/effect/turf_decal/trimline/brown/filled/line{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"dDi" = (
/obj/effect/turf_decal/trimline/yellow/filled/corner{
dir = 4
@@ -14003,6 +14005,23 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/hallway/secondary/entry)
+"dMQ" = (
+/obj/effect/turf_decal/siding/thinplating{
+ dir = 4
+ },
+/obj/effect/turf_decal/trimline/dark_red/warning{
+ dir = 4
+ },
+/obj/structure/railing{
+ dir = 4
+ },
+/obj/structure/industrial_lift/public,
+/obj/machinery/elevator_control_panel/directional/east{
+ linked_elevator_id = "tram_lower_center_lift";
+ preset_destination_names = list("2"="Lower Deck","3"="Upper Deck")
+ },
+/turf/open/floor/plating/elevatorshaft,
+/area/station/maintenance/tram/mid)
"dNa" = (
/obj/machinery/bookbinder,
/obj/machinery/newscaster/directional/north,
@@ -15457,6 +15476,14 @@
},
/turf/open/floor/iron/grimy,
/area/station/service/chapel/office)
+"epQ" = (
+/obj/machinery/computer/atmos_control/oxygen_tank{
+ atmos_chambers = list("o2ordance"="Oxygen Supply")
+ },
+/obj/effect/turf_decal/stripes/line,
+/obj/machinery/airalarm/directional/north,
+/turf/open/floor/iron/dark,
+/area/station/science/ordnance/storage)
"eqi" = (
/obj/effect/landmark/navigate_destination/tcomms,
/turf/open/floor/iron,
@@ -15682,19 +15709,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/wood,
/area/station/service/theater)
-"euR" = (
-/obj/effect/turf_decal/delivery,
-/obj/machinery/navbeacon{
- codes_txt = "delivery;dir=2";
- location = "QM #3"
- },
-/obj/effect/turf_decal/tile/brown/fourcorners,
-/mob/living/simple_animal/bot/mulebot{
- home_destination = "QM #3";
- suffix = "#3"
- },
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"euS" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -17627,6 +17641,15 @@
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
/area/station/science/lower)
+"fiy" = (
+/obj/effect/turf_decal/delivery,
+/obj/machinery/navbeacon{
+ codes_txt = "delivery;dir=1";
+ location = "QM #5"
+ },
+/obj/effect/turf_decal/tile/brown/fourcorners,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"fiP" = (
/obj/structure/table,
/obj/item/storage/toolbox/electrical{
@@ -18003,10 +18026,6 @@
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/science/ordnance)
-"foU" = (
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"foY" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -19676,14 +19695,6 @@
},
/turf/open/floor/iron/dark,
/area/station/security/processing)
-"fWK" = (
-/obj/machinery/computer/atmos_control/oxygen_tank{
- atmos_chambers = list("o2ordance"="Oxygen Supply")
- },
-/obj/effect/turf_decal/stripes/line,
-/obj/machinery/airalarm/directional/north,
-/turf/open/floor/iron/dark,
-/area/station/science/ordnance/storage)
"fWM" = (
/obj/effect/turf_decal/trimline/red/filled/line,
/obj/item/kirbyplants/random,
@@ -20242,20 +20253,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/tram/right)
-"giW" = (
-/obj/effect/turf_decal/trimline/dark_red/warning{
- dir = 9
- },
-/obj/structure/industrial_lift/public,
-/obj/structure/railing{
- dir = 9
- },
-/obj/machinery/elevator_control_panel/directional/west{
- linked_elevator_id = "tram_sci_lift";
- preset_destination_names = list("2"="Lower Deck","3"="Upper Deck")
- },
-/turf/open/floor/plating/elevatorshaft,
-/area/station/science/lower)
"giZ" = (
/obj/structure/bed,
/obj/effect/spawner/random/contraband/prison,
@@ -20881,6 +20878,19 @@
/obj/effect/turf_decal/trimline/red/filled/corner,
/turf/open/floor/iron,
/area/station/security/courtroom)
+"gtA" = (
+/obj/effect/turf_decal/delivery,
+/obj/machinery/navbeacon{
+ codes_txt = "delivery;dir=2";
+ location = "QM #1"
+ },
+/obj/effect/turf_decal/tile/brown/fourcorners,
+/mob/living/simple_animal/bot/mulebot{
+ home_destination = "QM #1";
+ suffix = "#1"
+ },
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"gtH" = (
/obj/structure/table/glass,
/obj/effect/turf_decal/trimline/red/filled/line{
@@ -21964,6 +21974,15 @@
/obj/item/papercutter,
/turf/open/floor/plating,
/area/station/security/warden)
+"gNM" = (
+/obj/machinery/elevator_control_panel{
+ layer = 3.1;
+ linked_elevator_id = "tram_xeno_lift";
+ pixel_y = 2;
+ preset_destination_names = list("2"="Lower Deck","3"="Upper Deck")
+ },
+/turf/closed/wall/r_wall,
+/area/station/science/xenobiology)
"gNN" = (
/obj/machinery/vending/wardrobe/coroner_wardrobe,
/obj/structure/window/reinforced/spawner/directional/west,
@@ -22345,11 +22364,6 @@
},
/turf/open/floor/iron/dark,
/area/station/medical/break_room)
-"gUL" = (
-/obj/effect/landmark/event_spawn,
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"gUO" = (
/obj/effect/turf_decal/trimline/neutral/filled/line,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -23934,13 +23948,6 @@
},
/turf/open/floor/iron/white,
/area/station/science/xenobiology)
-"hDU" = (
-/obj/effect/turf_decal/siding/thinplating/corner{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"hDZ" = (
/obj/effect/turf_decal/sand/plating,
/obj/effect/turf_decal/box,
@@ -24713,6 +24720,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/hallway/secondary/exit)
+"hSy" = (
+/obj/effect/turf_decal/siding/thinplating/corner{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"hSH" = (
/obj/structure/chair{
dir = 1
@@ -25083,6 +25097,20 @@
},
/turf/open/floor/iron,
/area/station/tcommsat/computer)
+"hZM" = (
+/obj/effect/turf_decal/trimline/dark_red/warning{
+ dir = 9
+ },
+/obj/structure/industrial_lift/public,
+/obj/structure/railing{
+ dir = 9
+ },
+/obj/machinery/elevator_control_panel/directional/west{
+ linked_elevator_id = "tram_sci_lift";
+ preset_destination_names = list("2"="Lower Deck","3"="Upper Deck")
+ },
+/turf/open/floor/plating/elevatorshaft,
+/area/station/science/lower)
"hZP" = (
/obj/structure/railing/corner{
dir = 8
@@ -28088,6 +28116,16 @@
/obj/structure/cable,
/turf/closed/wall/r_wall,
/area/station/ai_monitored/turret_protected/aisat/hallway)
+"jfE" = (
+/obj/effect/turf_decal/trimline/dark_red/warning,
+/obj/structure/industrial_lift/public,
+/obj/machinery/elevator_control_panel/directional/south{
+ linked_elevator_id = "tram_dorm_lift";
+ preset_destination_names = list("2"="Lower Deck","3"="Upper Deck")
+ },
+/obj/structure/railing,
+/turf/open/floor/plating/elevatorshaft,
+/area/station/maintenance/tram/left)
"jfH" = (
/obj/effect/turf_decal/trimline/red/filled/corner{
dir = 1
@@ -28584,14 +28622,6 @@
},
/turf/open/floor/iron,
/area/station/security/checkpoint/supply)
-"jnL" = (
-/obj/effect/turf_decal/trimline/brown/filled/line{
- dir = 1
- },
-/obj/effect/turf_decal/trimline/brown/filled/line,
-/obj/machinery/light/small/directional/west,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"jnR" = (
/obj/structure/bed{
dir = 8
@@ -28806,6 +28836,20 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/hallway/secondary/exit/departure_lounge)
+"jrl" = (
+/obj/effect/turf_decal/caution/stand_clear/red{
+ dir = 1
+ },
+/obj/structure/industrial_lift/public,
+/obj/structure/railing{
+ dir = 8
+ },
+/obj/machinery/elevator_control_panel/directional/west{
+ linked_elevator_id = "tram_perma_lift";
+ preset_destination_names = list("2"="Lower Deck","3"="Upper Deck")
+ },
+/turf/open/floor/plating/elevatorshaft,
+/area/station/security/execution/transfer)
"jrI" = (
/obj/structure/disposalpipe/trunk/multiz{
dir = 4
@@ -29081,27 +29125,6 @@
/obj/machinery/light/directional/north,
/turf/open/floor/iron/showroomfloor,
/area/station/security/lockers)
-"jwP" = (
-/obj/effect/landmark/lift_id{
- specific_lift_id = "tram_cargo_lift"
- },
-/obj/structure/railing{
- dir = 8
- },
-/obj/effect/turf_decal/trimline/dark_red/warning{
- dir = 8
- },
-/obj/structure/industrial_lift/public,
-/obj/machinery/elevator_control_panel/directional/west{
- linked_elevator_id = "tram_cargo_lift";
- preset_destination_names = list("2"="Lower Deck","3"="Upper Deck");
- req_access = list("mining")
- },
-/obj/effect/abstract/elevator_music_zone{
- linked_elevator_id = "tram_cargo_lift"
- },
-/turf/open/floor/plating/elevatorshaft,
-/area/station/cargo/miningdock)
"jwT" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -30342,13 +30365,6 @@
},
/turf/open/floor/iron,
/area/station/construction/mining/aux_base)
-"jTQ" = (
-/obj/effect/turf_decal/trimline/brown/filled/line{
- dir = 1
- },
-/obj/effect/turf_decal/trimline/brown/filled/line,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"jUa" = (
/obj/effect/turf_decal/trimline/purple/filled/corner{
dir = 4
@@ -34430,6 +34446,7 @@
/area/station/cargo/sorting)
"lnh" = (
/obj/machinery/door/poddoor/massdriver_chapel,
+/obj/structure/fans/tiny,
/turf/open/floor/plating,
/area/station/service/chapel/monastery)
"lnk" = (
@@ -34943,20 +34960,6 @@
/obj/effect/turf_decal/tile/red/fourcorners,
/turf/open/floor/iron/dark,
/area/station/security/office)
-"lvz" = (
-/obj/effect/turf_decal/caution/stand_clear/red{
- dir = 1
- },
-/obj/structure/industrial_lift/public,
-/obj/structure/railing{
- dir = 8
- },
-/obj/machinery/elevator_control_panel/directional/west{
- linked_elevator_id = "tram_perma_lift";
- preset_destination_names = list("2"="Lower Deck","3"="Upper Deck")
- },
-/turf/open/floor/plating/elevatorshaft,
-/area/station/security/execution/transfer)
"lvH" = (
/obj/effect/turf_decal/trimline/red/filled/line{
dir = 1
@@ -36302,24 +36305,6 @@
},
/turf/open/floor/iron,
/area/station/security/prison/safe)
-"lTM" = (
-/obj/effect/turf_decal/trimline/brown/filled/corner{
- dir = 8
- },
-/obj/effect/turf_decal/trimline/brown/filled/corner{
- dir = 1
- },
-/obj/effect/turf_decal/siding/thinplating{
- dir = 1
- },
-/obj/effect/turf_decal/loading_area{
- dir = 1
- },
-/obj/effect/turf_decal/stripes/corner{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"lTP" = (
/obj/structure/stairs/south,
/turf/open/floor/iron/stairs/medium{
@@ -37442,13 +37427,6 @@
/obj/machinery/meter,
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
-"mmX" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/trimline/neutral/filled/line{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/cargo/warehouse)
"mng" = (
/obj/structure/window/reinforced/plasma/spawner/directional/west,
/obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible,
@@ -37645,15 +37623,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/white,
/area/station/medical/storage)
-"mrg" = (
-/obj/effect/turf_decal/delivery,
-/obj/machinery/navbeacon{
- codes_txt = "delivery;dir=1";
- location = "QM #4"
- },
-/obj/effect/turf_decal/tile/brown/fourcorners,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"mrr" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/trimline/neutral/filled/line,
@@ -39024,20 +38993,6 @@
/obj/item/storage/secure/safe/directional/north,
/turf/open/floor/carpet,
/area/station/command/heads_quarters/hop)
-"mUc" = (
-/obj/structure/railing{
- dir = 1
- },
-/obj/machinery/elevator_control_panel/directional/north{
- linked_elevator_id = "tram_upper_center_lift";
- preset_destination_names = list("2"="Lower Deck","3"="Upper Deck")
- },
-/obj/effect/turf_decal/trimline/dark_red/warning{
- dir = 1
- },
-/obj/structure/industrial_lift/public,
-/turf/open/floor/plating/elevatorshaft,
-/area/station/maintenance/tram/mid)
"mUd" = (
/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/monitored/air_output{
dir = 1
@@ -39609,15 +39564,6 @@
},
/turf/open/floor/iron,
/area/station/maintenance/tram/right)
-"nfZ" = (
-/obj/effect/turf_decal/delivery,
-/obj/machinery/navbeacon{
- codes_txt = "delivery;dir=1";
- location = "QM #5"
- },
-/obj/effect/turf_decal/tile/brown/fourcorners,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"ngg" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden,
/obj/effect/spawner/structure/window/reinforced,
@@ -40674,6 +40620,27 @@
},
/turf/open/openspace,
/area/station/hallway/primary/tram/center)
+"nxj" = (
+/obj/effect/landmark/lift_id{
+ specific_lift_id = "tram_cargo_lift"
+ },
+/obj/structure/railing{
+ dir = 8
+ },
+/obj/effect/turf_decal/trimline/dark_red/warning{
+ dir = 8
+ },
+/obj/structure/industrial_lift/public,
+/obj/machinery/elevator_control_panel/directional/west{
+ linked_elevator_id = "tram_cargo_lift";
+ preset_destination_names = list("2"="Lower Deck","3"="Upper Deck");
+ req_access = list("mining")
+ },
+/obj/effect/abstract/elevator_music_zone{
+ linked_elevator_id = "tram_cargo_lift"
+ },
+/turf/open/floor/plating/elevatorshaft,
+/area/station/cargo/miningdock)
"nxq" = (
/obj/structure/table/wood,
/obj/structure/cable,
@@ -41264,6 +41231,20 @@
/obj/structure/chair,
/turf/open/floor/iron,
/area/station/security/checkpoint/supply)
+"nJb" = (
+/obj/structure/railing{
+ dir = 1
+ },
+/obj/machinery/elevator_control_panel/directional/north{
+ linked_elevator_id = "tram_upper_center_lift";
+ preset_destination_names = list("2"="Lower Deck","3"="Upper Deck")
+ },
+/obj/effect/turf_decal/trimline/dark_red/warning{
+ dir = 1
+ },
+/obj/structure/industrial_lift/public,
+/turf/open/floor/plating/elevatorshaft,
+/area/station/maintenance/tram/mid)
"nJd" = (
/obj/effect/turf_decal/trimline/red/filled/line{
dir = 5
@@ -41916,19 +41897,6 @@
/obj/effect/turf_decal/trimline/purple/filled/line,
/turf/open/floor/iron/white,
/area/station/science/lobby)
-"nUF" = (
-/obj/effect/turf_decal/delivery,
-/obj/machinery/navbeacon{
- codes_txt = "delivery;dir=2";
- location = "QM #1"
- },
-/obj/effect/turf_decal/tile/brown/fourcorners,
-/mob/living/simple_animal/bot/mulebot{
- home_destination = "QM #1";
- suffix = "#1"
- },
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"nUM" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -42079,13 +42047,6 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron/dark,
/area/station/medical/morgue)
-"nXk" = (
-/obj/effect/turf_decal/siding/thinplating{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"nXn" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -43939,15 +43900,6 @@
/obj/structure/grille,
/turf/open/space/openspace,
/area/space/nearstation)
-"oKn" = (
-/obj/machinery/elevator_control_panel{
- layer = 3.1;
- linked_elevator_id = "tram_xeno_lift";
- pixel_y = 2;
- preset_destination_names = list("2"="Lower Deck","3"="Upper Deck")
- },
-/turf/closed/wall/r_wall,
-/area/station/science/xenobiology)
"oKZ" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -45259,19 +45211,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/commons/vacant_room)
-"plH" = (
-/obj/effect/turf_decal/delivery,
-/obj/machinery/navbeacon{
- codes_txt = "delivery;dir=2";
- location = "QM #2"
- },
-/obj/effect/turf_decal/tile/brown/fourcorners,
-/mob/living/simple_animal/bot/mulebot{
- home_destination = "QM #2";
- suffix = "#2"
- },
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"plQ" = (
/obj/effect/turf_decal/trimline/red/filled/corner,
/obj/structure/disposalpipe/segment{
@@ -46187,6 +46126,19 @@
/obj/effect/turf_decal/tile/bar/opposingcorners,
/turf/open/floor/iron,
/area/station/cargo/miningdock/cafeteria)
+"pzi" = (
+/obj/effect/turf_decal/delivery,
+/obj/machinery/navbeacon{
+ codes_txt = "delivery;dir=1";
+ location = "QM #6"
+ },
+/obj/effect/turf_decal/tile/brown/fourcorners,
+/mob/living/simple_animal/bot/mulebot{
+ home_destination = "QM #6";
+ suffix = "#6"
+ },
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"pzv" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 8
@@ -47099,15 +47051,6 @@
/obj/structure/railing,
/turf/open/floor/plating/elevatorshaft,
/area/station/maintenance/tram/left)
-"pOL" = (
-/obj/effect/turf_decal/trimline/neutral/filled/line{
- dir = 1
- },
-/obj/effect/decal/cleanable/dirt,
-/obj/structure/table,
-/obj/machinery/light/dim/directional/north,
-/turf/open/floor/iron,
-/area/station/cargo/warehouse)
"pOQ" = (
/obj/effect/turf_decal/trimline/neutral/filled/line{
dir = 4
@@ -47845,6 +47788,14 @@
/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/station/commons/fitness/recreation/entertainment)
+"qey" = (
+/obj/effect/turf_decal/trimline/brown/filled/line{
+ dir = 1
+ },
+/obj/effect/turf_decal/trimline/brown/filled/line,
+/obj/machinery/light/small/directional/west,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"qez" = (
/obj/machinery/computer/slot_machine{
pixel_y = 2
@@ -49755,6 +49706,15 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/commons/dorms)
+"qPL" = (
+/obj/machinery/elevator_control_panel{
+ layer = 3.1;
+ linked_elevator_id = "tram_xeno_lift";
+ pixel_y = 2;
+ preset_destination_names = list("2"="Lower Deck","3"="Upper Deck")
+ },
+/turf/closed/wall,
+/area/station/science/xenobiology)
"qPV" = (
/obj/machinery/power/apc/auto_name/directional/south,
/obj/structure/cable,
@@ -51421,6 +51381,10 @@
/obj/effect/turf_decal/stripes/white/line,
/turf/open/floor/iron,
/area/station/hallway/primary/tram/center)
+"rqH" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"rre" = (
/obj/effect/turf_decal/trimline/neutral/filled/line,
/obj/effect/landmark/start/hangover,
@@ -51643,15 +51607,6 @@
/obj/effect/turf_decal/sand/plating,
/turf/open/floor/plating/airless,
/area/station/asteroid)
-"rwo" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/obj/effect/turf_decal/trimline/brown/filled/line{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"rws" = (
/obj/structure/table/glass,
/obj/item/storage/box/monkeycubes{
@@ -57051,10 +57006,6 @@
/obj/structure/cable,
/turf/open/floor/iron/freezer,
/area/station/security/prison/shower)
-"tte" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"tth" = (
/obj/effect/landmark/event_spawn,
/obj/structure/cable,
@@ -58147,6 +58098,19 @@
/obj/effect/landmark/start/chemist,
/turf/open/floor/iron/white,
/area/station/medical/chemistry)
+"tMq" = (
+/obj/effect/turf_decal/delivery,
+/obj/machinery/navbeacon{
+ codes_txt = "delivery;dir=2";
+ location = "QM #3"
+ },
+/obj/effect/turf_decal/tile/brown/fourcorners,
+/mob/living/simple_animal/bot/mulebot{
+ home_destination = "QM #3";
+ suffix = "#3"
+ },
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"tMw" = (
/obj/effect/turf_decal/trimline/purple/filled/corner{
dir = 1
@@ -59788,6 +59752,15 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/station/maintenance/tram/mid)
+"uoG" = (
+/obj/effect/turf_decal/delivery,
+/obj/machinery/navbeacon{
+ codes_txt = "delivery;dir=1";
+ location = "QM #4"
+ },
+/obj/effect/turf_decal/tile/brown/fourcorners,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"uoJ" = (
/obj/structure/closet/secure_closet/security/science,
/obj/item/clothing/mask/whistle,
@@ -60101,23 +60074,6 @@
/obj/effect/spawner/random/maintenance/five,
/turf/open/floor/iron,
/area/station/cargo/warehouse)
-"uud" = (
-/obj/effect/turf_decal/siding/thinplating{
- dir = 4
- },
-/obj/effect/turf_decal/trimline/dark_red/warning{
- dir = 4
- },
-/obj/structure/railing{
- dir = 4
- },
-/obj/structure/industrial_lift/public,
-/obj/machinery/elevator_control_panel/directional/east{
- linked_elevator_id = "tram_lower_center_lift";
- preset_destination_names = list("2"="Lower Deck","3"="Upper Deck")
- },
-/turf/open/floor/plating/elevatorshaft,
-/area/station/maintenance/tram/mid)
"uue" = (
/obj/machinery/power/turbine/turbine_outlet{
dir = 4
@@ -60184,6 +60140,12 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/commons/fitness)
+"uvt" = (
+/obj/machinery/cryo_cell{
+ dir = 4
+ },
+/turf/open/floor/iron/dark,
+/area/station/medical/treatment_center)
"uvu" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 8
@@ -61641,16 +61603,6 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/security/checkpoint/arrivals)
-"uSl" = (
-/obj/effect/turf_decal/trimline/dark_red/warning,
-/obj/structure/industrial_lift/public,
-/obj/machinery/elevator_control_panel/directional/south{
- linked_elevator_id = "tram_dorm_lift";
- preset_destination_names = list("2"="Lower Deck","3"="Upper Deck")
- },
-/obj/structure/railing,
-/turf/open/floor/plating/elevatorshaft,
-/area/station/maintenance/tram/left)
"uSL" = (
/obj/effect/turf_decal/delivery/white,
/obj/structure/fluff/tram_rail/floor,
@@ -64099,6 +64051,15 @@
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/science/ordnance)
+"vJS" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/obj/effect/turf_decal/trimline/brown/filled/line{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"vKd" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -64296,6 +64257,17 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/security/checkpoint/supply)
+"vNx" = (
+/obj/machinery/door/airlock/mining/glass{
+ name = "MULE Storage"
+ },
+/obj/effect/turf_decal/trimline/brown/filled/line{
+ dir = 1
+ },
+/obj/effect/turf_decal/trimline/brown/filled/line,
+/obj/effect/mapping_helpers/airlock/access/all/supply/general,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"vNB" = (
/obj/effect/turf_decal/box,
/obj/effect/turf_decal/trimline/yellow/filled/line{
@@ -65077,6 +65049,15 @@
/obj/machinery/door/firedoor,
/turf/open/floor/iron,
/area/station/hallway/secondary/service)
+"wcZ" = (
+/obj/effect/turf_decal/trimline/neutral/filled/line{
+ dir = 1
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/table,
+/obj/machinery/light/dim/directional/north,
+/turf/open/floor/iron,
+/area/station/cargo/warehouse)
"wda" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
dir = 8
@@ -65614,6 +65595,10 @@
},
/turf/open/floor/iron/dark,
/area/station/service/chapel/monastery)
+"wod" = (
+/obj/structure/cable,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"wop" = (
/obj/structure/industrial_lift/public,
/obj/effect/turf_decal/caution/stand_clear/red,
@@ -67153,6 +67138,19 @@
/obj/structure/sink/directional/south,
/turf/open/floor/iron/white,
/area/station/medical/virology)
+"wTp" = (
+/obj/effect/turf_decal/delivery,
+/obj/machinery/navbeacon{
+ codes_txt = "delivery;dir=2";
+ location = "QM #2"
+ },
+/obj/effect/turf_decal/tile/brown/fourcorners,
+/mob/living/simple_animal/bot/mulebot{
+ home_destination = "QM #2";
+ suffix = "#2"
+ },
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"wTy" = (
/obj/machinery/button/crematorium{
id = "crematoriumChapel";
@@ -67759,6 +67757,13 @@
/obj/item/papercutter,
/turf/open/floor/iron,
/area/station/command/bridge)
+"xhg" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/trimline/neutral/filled/line{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/cargo/warehouse)
"xhk" = (
/obj/effect/turf_decal/trimline/neutral/filled/line{
dir = 4
@@ -68402,6 +68407,13 @@
},
/turf/open/floor/iron,
/area/station/security/brig)
+"xup" = (
+/obj/effect/turf_decal/siding/thinplating{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron,
+/area/station/cargo/storage)
"xuq" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 4
@@ -68862,17 +68874,6 @@
"xDQ" = (
/turf/closed/wall,
/area/station/security/processing)
-"xDW" = (
-/obj/machinery/door/airlock/mining/glass{
- name = "MULE Storage"
- },
-/obj/effect/turf_decal/trimline/brown/filled/line{
- dir = 1
- },
-/obj/effect/turf_decal/trimline/brown/filled/line,
-/obj/effect/mapping_helpers/airlock/access/all/supply/general,
-/turf/open/floor/iron,
-/area/station/cargo/storage)
"xDY" = (
/obj/structure/railing{
dir = 8
@@ -86187,7 +86188,7 @@ jWs
lDo
ucA
wox
-lvz
+jrl
gTv
jWs
aaa
@@ -92394,7 +92395,7 @@ ncF
ncF
dFS
tuU
-uSl
+jfE
elr
elr
elr
@@ -99829,7 +99830,7 @@ uTz
hJM
nAa
ekB
-mUc
+nJb
jSV
uuD
qjU
@@ -104473,7 +104474,7 @@ qjU
aaa
qjU
fok
-uud
+dMQ
sNq
ceb
pcx
@@ -113437,7 +113438,7 @@ aaa
aaa
uGW
jdU
-jwP
+nxj
rff
uGW
aaa
@@ -113735,7 +113736,7 @@ abM
abM
abM
iix
-giW
+hZM
boW
iix
abM
@@ -116329,7 +116330,7 @@ hDT
keT
iEF
fof
-csn
+qPL
sXX
akC
hFP
@@ -120936,7 +120937,7 @@ kkK
jXE
lwF
dfz
-fWK
+epQ
qCP
urA
ygC
@@ -167455,9 +167456,9 @@ pIk
oIU
aMG
xdx
-cEy
+uvt
uVW
-cEy
+uvt
jtr
dSZ
aOO
@@ -179481,9 +179482,9 @@ aaa
aaa
aaa
cTU
-euR
-jnL
-abN
+tMq
+qey
+pzi
cTU
cTU
ohS
@@ -179738,9 +179739,9 @@ aaa
aaa
aaa
cTU
-plH
-jTQ
-nfZ
+wTp
+aVM
+fiy
cTU
exr
pZA
@@ -179995,9 +179996,9 @@ aac
aaa
aaa
cTU
-nUF
-jTQ
-mrg
+gtA
+aVM
+uoG
cTU
lan
pZA
@@ -180253,7 +180254,7 @@ aaa
cTU
cTU
ohS
-xDW
+vNx
ohS
cTU
nnb
@@ -180510,10 +180511,10 @@ aaa
cTU
blx
tAJ
-lTM
-axF
-axF
-rwo
+aWQ
+dCY
+dCY
+vJS
dij
uax
uax
@@ -180772,8 +180773,8 @@ uax
uax
uax
uax
-gUL
-foU
+aZT
+wod
dzw
msn
qza
@@ -181028,9 +181029,9 @@ uax
uax
uax
uax
-tte
-nXk
-hDU
+rqH
+xup
+hSy
dzw
sxR
skb
@@ -181611,7 +181612,7 @@ eJQ
bNx
aSt
aSt
-oKn
+gNM
aaa
aaa
aaa
@@ -183339,7 +183340,7 @@ cTU
cTU
cTU
udQ
-mmX
+xhg
pxD
ayd
ayt
@@ -183853,7 +183854,7 @@ aaa
aaa
aaa
udQ
-pOL
+wcZ
kXr
aye
rgg
diff --git a/_maps/shuttles/emergency_cere.dmm b/_maps/shuttles/emergency_cere.dmm
index c964d37011f..07e236344ab 100644
--- a/_maps/shuttles/emergency_cere.dmm
+++ b/_maps/shuttles/emergency_cere.dmm
@@ -478,7 +478,7 @@
/turf/open/floor/iron/white,
/area/shuttle/escape)
"ck" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/obj/effect/turf_decal/tile/blue/half/contrasted{
dir = 1
},
diff --git a/_maps/shuttles/pirate_ex_interdyne.dmm b/_maps/shuttles/pirate_ex_interdyne.dmm
index c3f7e186acb..5d2149c049f 100644
--- a/_maps/shuttles/pirate_ex_interdyne.dmm
+++ b/_maps/shuttles/pirate_ex_interdyne.dmm
@@ -301,7 +301,7 @@
/area/shuttle/pirate)
"aW" = (
/obj/effect/turf_decal/tile/dark_blue/opposingcorners,
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/turf/open/floor/iron/dark,
/area/shuttle/pirate)
"be" = (
diff --git a/_maps/shuttles/pirate_geode.dmm b/_maps/shuttles/pirate_geode.dmm
index eb7f8e5c78f..d2e8f034f48 100644
--- a/_maps/shuttles/pirate_geode.dmm
+++ b/_maps/shuttles/pirate_geode.dmm
@@ -1,30 +1,26 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
"at" = (
-/obj/structure/grille,
-/obj/effect/spawner/structure/window/hollow/survival_pod,
-/obj/machinery/door/poddoor/shutters/preopen{
- id = "geodebridge"
- },
-/turf/open/misc/dirt{
- planetary_atmos = 0;
- initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
- },
+/obj/structure/barricade/wooden,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"aM" = (
-/obj/machinery/power/shuttle_engine/huge{
- dir = 8
- },
-/obj/effect/turf_decal/stripes/white/line{
+/obj/structure/table/wood,
+/obj/machinery/light/small/blacklight/directional{
dir = 8
},
-/turf/open/floor/plating,
+/obj/item/restraints/legcuffs/beartrap,
+/obj/item/restraints/legcuffs/beartrap,
+/obj/item/restraints/legcuffs/beartrap,
+/obj/item/grenade/c4,
+/obj/item/grenade/c4,
+/obj/item/grenade/c4,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"bY" = (
-/obj/effect/turf_decal/lunar_sand/plating,
-/obj/effect/turf_decal/weather/dirt{
- dir = 9
+/obj/machinery/atmospherics/components/unary/vent_pump/on{
+ dir = 1
},
-/turf/open/floor/plating,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"cx" = (
/obj/effect/turf_decal/lunar_sand/plating,
@@ -48,8 +44,8 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"ev" = (
-/obj/structure/flora/lunar_plant/style_2,
-/turf/open/misc/dirt/jungle,
+/obj/machinery/computer/piratepad_control,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"fB" = (
/obj/effect/turf_decal/lunar_sand/plating,
@@ -67,10 +63,8 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"ga" = (
-/obj/item/stack/sheet/bluespace_crystal{
- amount = 2
- },
-/turf/open/misc/dirt/jungle,
+/obj/machinery/space_heater,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"ge" = (
/obj/effect/turf_decal/lunar_sand/plating,
@@ -86,21 +80,22 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"gv" = (
-/obj/item/reagent_containers/cup/beaker/large,
-/turf/open/misc/dirt/jungle,
+/obj/machinery/suit_storage_unit/pirate{
+ helmet_type = /obj/item/clothing/head/helmet/space/syndicate/blue;
+ suit_type = /obj/item/clothing/suit/space/syndicate/blue
+ },
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"gM" = (
-/obj/structure/barricade/wooden,
-/turf/open/misc/dirt,
+/obj/structure/flora/lunar_plant/style_2,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"hM" = (
-/obj/item/stack/sheet/bluespace_crystal,
-/obj/machinery/button/door{
- id = "geodebridge";
- name = "Window Shutters Control";
- pixel_y = 30
+/obj/machinery/porta_turret/syndicate/teleport{
+ dir = 4;
+ faction = list("pirate")
},
-/turf/open/misc/dirt/jungle,
+/turf/closed/wall/mineral/plastitanium/nodiagonal,
/area/shuttle/pirate)
"id" = (
/obj/effect/turf_decal/lunar_sand/plating,
@@ -159,14 +154,13 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"ka" = (
-/obj/machinery/light/small/blacklight/directional{
- dir = 4
- },
-/turf/open/misc/dirt/jungle,
+/obj/effect/turf_decal/lunar_sand/plating,
+/obj/item/trash/energybar,
+/turf/open/floor/plating,
/area/shuttle/pirate)
"ko" = (
-/obj/machinery/piratepad,
-/turf/open/misc/dirt/jungle,
+/obj/item/trash/energybar,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"kp" = (
/obj/effect/turf_decal/lunar_sand/plating,
@@ -198,12 +192,8 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"kV" = (
-/obj/item/stack/sheet/bluespace_crystal{
- amount = 2
- },
-/obj/structure/table/wood,
-/obj/machinery/reagentgrinder,
-/turf/open/misc/dirt/jungle,
+/obj/item/reagent_containers/cup/beaker/large,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"lt" = (
/turf/template_noop,
@@ -221,20 +211,17 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"mv" = (
-/turf/open/misc/dirt,
+/obj/machinery/porta_turret/syndicate/teleport{
+ dir = 8;
+ faction = list("pirate")
+ },
+/turf/closed/wall/mineral/plastitanium/nodiagonal,
/area/shuttle/pirate)
"nk" = (
-/obj/structure/table/wood,
-/obj/machinery/light/small/blacklight/directional{
- dir = 8
+/obj/item/stack/sheet/bluespace_crystal{
+ amount = 2
},
-/obj/item/restraints/legcuffs/beartrap,
-/obj/item/restraints/legcuffs/beartrap,
-/obj/item/restraints/legcuffs/beartrap,
-/obj/item/grenade/c4,
-/obj/item/grenade/c4,
-/obj/item/grenade/c4,
-/turf/open/misc/dirt/jungle,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"nD" = (
/obj/machinery/light/small/blacklight/directional{
@@ -315,8 +302,13 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"qp" = (
-/obj/structure/reagent_dispensers/fueltank,
-/turf/open/misc/dirt/jungle,
+/obj/item/stack/sheet/bluespace_crystal,
+/obj/machinery/button/door{
+ id = "geodebridge";
+ name = "Window Shutters Control";
+ pixel_y = 30
+ },
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"qK" = (
/obj/effect/turf_decal/lunar_sand/plating,
@@ -343,6 +335,12 @@
},
/turf/open/floor/plating,
/area/shuttle/pirate)
+"rn" = (
+/obj/structure/closet/crate/miningcar,
+/obj/effect/spawner/random/maintenance/three,
+/obj/item/mining_scanner,
+/turf/open/misc/dirt/station,
+/area/shuttle/pirate)
"rG" = (
/obj/effect/turf_decal/lunar_sand/plating,
/obj/effect/turf_decal/weather/dirt{
@@ -383,6 +381,17 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"uH" = (
+/obj/effect/turf_decal/lunar_sand/plating,
+/obj/effect/turf_decal/weather/dirt{
+ dir = 8
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
+ dir = 4
+ },
+/obj/machinery/light/small/blacklight/directional{
+ dir = 8
+ },
+/obj/effect/spawner/random/trash/mess,
/turf/open/floor/plating,
/area/shuttle/pirate)
"uP" = (
@@ -395,10 +404,21 @@
},
/turf/open/floor/iron/dark,
/area/shuttle/pirate)
+"vj" = (
+/obj/machinery/computer/shuttle/pirate{
+ dir = 8
+ },
+/turf/open/misc/dirt/station,
+/area/shuttle/pirate)
"vl" = (
+/obj/effect/spawner/random/maintenance,
+/obj/item/shovel,
/obj/structure/closet/crate/miningcar,
-/obj/effect/spawner/random/maintenance/three,
-/turf/open/misc/dirt/jungle,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/rods{
+ amount = 5
+ },
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"vP" = (
/obj/structure/table/reinforced,
@@ -431,16 +451,24 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"wz" = (
-/obj/machinery/computer/piratepad_control,
-/turf/open/misc/dirt/jungle,
+/obj/effect/turf_decal/lunar_sand/plating,
+/obj/effect/turf_decal/weather/dirt{
+ dir = 3
+ },
+/obj/effect/turf_decal/weather/dirt{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/shreds,
+/turf/open/floor/plating,
/area/shuttle/pirate)
"xg" = (
/obj/structure/grille,
/obj/effect/spawner/structure/window/hollow/survival_pod,
-/turf/open/misc/dirt{
- planetary_atmos = 0;
- initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
- },
+/obj/structure/barricade/wooden/crude,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"xN" = (
/obj/effect/turf_decal/lunar_sand/plating,
@@ -450,8 +478,9 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"xS" = (
-/obj/structure/chair/wood,
-/turf/open/misc/dirt/jungle,
+/obj/structure/sign/poster/contraband/busty_backdoor_xeno_babes_6/directional/north,
+/obj/item/stack/ore/silver,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"yh" = (
/obj/structure/cable,
@@ -464,8 +493,8 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"yz" = (
-/obj/structure/flora/lunar_plant/style_1,
-/turf/open/misc/dirt/jungle,
+/obj/structure/flora/lunar_plant/style_3,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"zO" = (
/obj/effect/turf_decal/lunar_sand/plating,
@@ -475,28 +504,21 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"zS" = (
-/obj/effect/turf_decal/lunar_sand/plating,
-/obj/effect/turf_decal/weather/dirt{
- dir = 5
+/obj/item/stack/sheet/bluespace_crystal{
+ amount = 2
},
-/turf/open/floor/plating,
+/obj/structure/table/wood,
+/obj/machinery/reagentgrinder,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"zZ" = (
-/obj/item/stack/sheet/bluespace_crystal,
-/turf/open/misc/dirt/jungle,
+/obj/structure/reagent_dispensers/watertank,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"At" = (
-/obj/effect/turf_decal/lunar_sand/plating,
-/obj/effect/turf_decal/weather/dirt{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
- dir = 4
- },
-/obj/machinery/light/small/blacklight/directional{
- dir = 8
+/turf/closed/mineral/random/jungle{
+ baseturfs = null
},
-/turf/open/floor/plating,
/area/shuttle/pirate)
"AT" = (
/obj/effect/turf_decal/lunar_sand/plating,
@@ -519,11 +541,13 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"BA" = (
-/obj/machinery/airalarm/directional/north,
-/obj/structure/table/wood,
-/obj/machinery/microwave,
-/obj/effect/mapping_helpers/airalarm/all_access,
-/turf/open/misc/dirt/jungle,
+/obj/structure/closet/crate/cardboard{
+ name = "box of climbing hooks"
+ },
+/obj/item/climbing_hook/syndicate,
+/obj/item/climbing_hook/syndicate,
+/obj/item/climbing_hook/syndicate,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"BI" = (
/obj/effect/turf_decal/lunar_sand/plating,
@@ -547,11 +571,8 @@
/turf/closed/wall/mineral/iron,
/area/shuttle/pirate)
"Ds" = (
-/obj/structure/rack,
-/obj/item/storage/box/syringes,
-/obj/item/storage/medkit/brute,
-/obj/item/storage/medkit/fire,
-/turf/open/misc/dirt/jungle,
+/obj/machinery/loot_locator,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"Dw" = (
/obj/machinery/power/port_gen/pacman{
@@ -575,14 +596,8 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"DT" = (
-/obj/effect/spawner/random/maintenance,
-/obj/item/shovel,
-/obj/structure/closet/crate/miningcar,
-/obj/item/stack/sheet/mineral/coal,
-/obj/item/stack/rods{
- amount = 5
- },
-/turf/open/misc/dirt/jungle,
+/obj/structure/fluff/minepost,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"Ec" = (
/obj/effect/turf_decal/lunar_sand/plating,
@@ -614,10 +629,8 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"Gj" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on{
- dir = 1
- },
-/turf/open/misc/dirt/jungle,
+/obj/machinery/piratepad,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"GQ" = (
/obj/effect/turf_decal/lunar_sand/plating,
@@ -641,12 +654,12 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"HJ" = (
-/obj/structure/reagent_dispensers/watertank,
-/turf/open/misc/dirt/jungle,
+/obj/machinery/shuttle_scrambler,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"HY" = (
-/obj/machinery/loot_locator,
-/turf/open/misc/dirt/jungle,
+/obj/effect/spawner/random/trash/mess,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"Ig" = (
/obj/effect/turf_decal/lunar_sand/plating,
@@ -691,6 +704,10 @@
},
/turf/open/floor/iron/dark,
/area/shuttle/pirate)
+"JK" = (
+/obj/item/stack/sheet/bluespace_crystal,
+/turf/open/misc/dirt/station,
+/area/shuttle/pirate)
"JL" = (
/obj/effect/turf_decal/lunar_sand/plating,
/obj/machinery/atmospherics/components/unary/vent_pump/on,
@@ -713,9 +730,8 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"KK" = (
-/obj/structure/sign/poster/contraband/busty_backdoor_xeno_babes_6/directional/north,
-/obj/item/stack/ore/silver,
-/turf/open/misc/dirt/jungle,
+/obj/structure/reagent_dispensers/fueltank,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"Mc" = (
/obj/effect/turf_decal/lunar_sand/plating,
@@ -764,17 +780,19 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"Nb" = (
-/obj/structure/grille,
-/obj/effect/spawner/structure/window/hollow/survival_pod,
-/obj/structure/barricade/wooden/crude,
-/turf/open/misc/dirt{
- planetary_atmos = 0;
- initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
- },
+/obj/structure/rack,
+/obj/item/storage/box/syringes,
+/obj/item/storage/medkit/brute,
+/obj/item/storage/medkit/fire,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"NT" = (
-/obj/structure/fluff/minepost,
-/turf/open/misc/dirt/jungle,
+/obj/effect/turf_decal/lunar_sand/plating,
+/obj/effect/turf_decal/weather/dirt{
+ dir = 9
+ },
+/obj/item/trash/energybar,
+/turf/open/floor/plating,
/area/shuttle/pirate)
"Od" = (
/turf/closed/wall/mineral/iron,
@@ -792,33 +810,6 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"OP" = (
-/obj/machinery/space_heater,
-/turf/open/misc/dirt/jungle,
-/area/shuttle/pirate)
-"OR" = (
-/obj/machinery/porta_turret/syndicate/teleport{
- faction = list("pirate")
- },
-/turf/closed/wall/mineral/iron,
-/area/shuttle/pirate)
-"OX" = (
-/obj/structure/sign/poster/contraband/bountyhunters,
-/turf/closed/wall/mineral/iron,
-/area/shuttle/pirate)
-"Pq" = (
-/obj/machinery/power/shuttle_engine/large{
- dir = 8
- },
-/obj/effect/turf_decal/stripes/white/line{
- dir = 8
- },
-/turf/open/floor/plating,
-/area/shuttle/pirate)
-"Pr" = (
-/obj/structure/flora/lunar_plant/style_3,
-/turf/open/misc/dirt/jungle,
-/area/shuttle/pirate)
-"PB" = (
/obj/structure/rack,
/obj/item/gun/energy/recharge/kinetic_accelerator{
pixel_y = 5
@@ -841,13 +832,45 @@
/obj/item/borg/upgrade/modkit/indoors{
pixel_y = -5
},
-/turf/open/misc/dirt/jungle,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
-"Qg" = (
-/obj/machinery/computer/shuttle/pirate{
+"OR" = (
+/obj/machinery/porta_turret/syndicate/teleport{
+ faction = list("pirate")
+ },
+/turf/closed/wall/mineral/iron,
+/area/shuttle/pirate)
+"OX" = (
+/obj/structure/sign/poster/contraband/bountyhunters,
+/turf/closed/wall/mineral/iron,
+/area/shuttle/pirate)
+"Pq" = (
+/obj/machinery/power/shuttle_engine/propulsion{
dir = 8
},
-/turf/open/misc/dirt/jungle,
+/turf/open/floor/plating,
+/area/shuttle/pirate)
+"Pr" = (
+/obj/structure/table/wood,
+/obj/item/food/energybar{
+ pixel_y = 9
+ },
+/obj/item/food/energybar,
+/turf/open/misc/dirt/station,
+/area/shuttle/pirate)
+"PB" = (
+/obj/machinery/light/small/blacklight/directional{
+ dir = 4
+ },
+/turf/open/misc/dirt/station,
+/area/shuttle/pirate)
+"Qg" = (
+/obj/structure/grille,
+/obj/effect/spawner/structure/window/hollow/survival_pod,
+/obj/machinery/door/poddoor/shutters/preopen{
+ id = "geodebridge"
+ },
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"Qo" = (
/turf/open/floor/iron/stairs{
@@ -864,8 +887,7 @@
/turf/open/floor/iron/dark,
/area/shuttle/pirate)
"Rp" = (
-/obj/machinery/shuttle_scrambler,
-/turf/open/misc/dirt/jungle,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"Rv" = (
/obj/effect/turf_decal/weather/dirt{
@@ -902,7 +924,8 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"Sy" = (
-/turf/open/misc/dirt/jungle,
+/obj/structure/chair/wood,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"SP" = (
/obj/effect/turf_decal/lunar_sand/plating,
@@ -915,8 +938,8 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"TC" = (
-/obj/effect/turf_decal/lunar_sand/plating,
-/turf/open/floor/plating,
+/obj/structure/flora/lunar_plant/style_1,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"Uf" = (
/obj/machinery/power/shuttle_engine/heater{
@@ -940,21 +963,16 @@
/turf/closed/wall/mineral/plastitanium/nodiagonal,
/area/shuttle/pirate)
"UM" = (
-/obj/item/stack/sheet/bluespace_crystal{
- amount = 2
- },
-/obj/machinery/light/small/blacklight/directional{
- dir = 8
- },
-/turf/open/misc/dirt/jungle,
+/obj/structure/grille,
+/obj/effect/spawner/structure/window/hollow/survival_pod,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"UY" = (
+/obj/machinery/airalarm/directional/north,
/obj/structure/table/wood,
-/obj/item/food/energybar{
- pixel_y = 9
- },
-/obj/item/food/energybar,
-/turf/open/misc/dirt/jungle,
+/obj/machinery/microwave,
+/obj/effect/mapping_helpers/airalarm/all_access,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
"WR" = (
/obj/effect/turf_decal/lunar_sand/plating,
@@ -994,11 +1012,13 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"ZF" = (
-/obj/machinery/suit_storage_unit/pirate{
- helmet_type = /obj/item/clothing/head/helmet/space/syndicate/blue;
- suit_type = /obj/item/clothing/suit/space/syndicate/blue
+/obj/item/stack/sheet/bluespace_crystal{
+ amount = 2
+ },
+/obj/machinery/light/small/blacklight/directional{
+ dir = 8
},
-/turf/open/misc/dirt/jungle,
+/turf/open/misc/dirt/station,
/area/shuttle/pirate)
(1,1,1) = {"
@@ -1007,68 +1027,47 @@ lt
lt
lt
lt
-lt
-lt
-lt
-yu
yu
-aM
-lt
-lt
-lt
-lt
-lt
-lt
-lt
-lt
-"}
-(2,1,1) = {"
-lt
-lt
-lt
-lt
-lt
yu
-Pq
jh
-uH
-uH
-uH
+yu
+yu
+yu
jh
yu
-Pq
+yu
lt
lt
lt
lt
lt
"}
-(3,1,1) = {"
+(2,1,1) = {"
lt
lt
lt
-jx
+mv
Od
-uH
-uH
-jx
-uH
-uH
-uH
-jx
-uH
-uH
+Pq
+Pq
+At
+Pq
+Pq
+Pq
+At
+Pq
+Pq
Od
-jx
+mv
lt
lt
lt
"}
-(4,1,1) = {"
+(3,1,1) = {"
lt
lt
-jx
-jx
+At
+At
Od
Uf
Uf
@@ -1080,18 +1079,18 @@ Od
Uf
Uf
Od
-jx
-jx
+At
+At
lt
lt
"}
-(5,1,1) = {"
+(4,1,1) = {"
lt
lt
jx
jx
Od
-NT
+DT
kp
Uw
Ku
@@ -1099,66 +1098,66 @@ ME
Dw
Uw
ZD
-NT
+DT
Od
jx
jx
lt
lt
"}
-(6,1,1) = {"
+(5,1,1) = {"
lt
lt
lt
jx
Od
-Sy
-zS
+Rp
+fO
IP
DM
JL
DM
SP
Ih
-ga
+nk
Od
jx
lt
lt
lt
"}
-(7,1,1) = {"
+(6,1,1) = {"
lt
jx
jx
jx
Od
-xS
-kV
+Sy
+zS
nR
WR
Oq
Mc
xN
wd
-OP
+ga
Od
jx
jx
jx
lt
"}
-(8,1,1) = {"
+(7,1,1) = {"
jx
jx
jx
jx
Od
-KK
-gv
-Sy
-Sy
-Sy
+xS
+kV
+ko
+Rp
+Rp
Od
Od
kM
@@ -1169,28 +1168,28 @@ jx
jx
jx
"}
-(9,1,1) = {"
+(8,1,1) = {"
jx
jx
jx
jx
Od
-ZF
-ZF
-ZF
-Ds
-PB
+gv
+gv
+gv
+Nb
+OP
Od
-Pr
+yz
Mm
-Sy
-vl
+Rp
+rn
Od
jx
jx
jx
"}
-(10,1,1) = {"
+(9,1,1) = {"
jx
jx
Od
@@ -1202,58 +1201,58 @@ Od
Od
Od
OX
-UY
+Pr
Mm
-ga
-DT
+nk
+vl
Od
jx
jx
jx
"}
-(11,1,1) = {"
+(10,1,1) = {"
lt
jt
Od
-NT
-UM
-yz
+DT
+ZF
+TC
Od
-Rp
-nk
-HY
+HJ
+aM
+Ds
Od
-BA
+UY
Mm
-Sy
-NT
+Rp
+DT
Od
Od
Od
lt
"}
-(12,1,1) = {"
+(11,1,1) = {"
lt
-gM
-xg
-bY
+at
+UM
+NT
oa
zO
Od
-Sy
-ga
-Sy
+Rp
+nk
+Rp
Od
-Sy
+BA
Mm
-Sy
+Rp
Dx
uk
St
AT
lt
"}
-(13,1,1) = {"
+(12,1,1) = {"
lt
XB
Od
@@ -1274,49 +1273,49 @@ Od
OR
lt
"}
-(14,1,1) = {"
+(13,1,1) = {"
lt
-mv
-Nb
+Rp
+xg
fO
pO
im
Od
-ev
-rG
-Gj
+gM
+wz
+bY
Od
-Sy
-zZ
-Sy
+HY
+JK
+Rp
lA
id
St
Fx
lt
"}
-(15,1,1) = {"
+(14,1,1) = {"
lt
jx
Od
-NT
-ka
-ga
+DT
+PB
+nk
Od
-wz
+ev
rG
-ko
+Gj
Od
-qp
-HJ
-Sy
-NT
+KK
+zZ
+Rp
+DT
Od
Od
Od
lt
"}
-(16,1,1) = {"
+(15,1,1) = {"
lt
jx
Od
@@ -1337,7 +1336,7 @@ jx
jx
lt
"}
-(17,1,1) = {"
+(16,1,1) = {"
lt
jx
Od
@@ -1345,7 +1344,7 @@ Er
YK
Qo
el
-At
+uH
kx
iu
iu
@@ -1358,14 +1357,14 @@ Od
jx
lt
"}
-(18,1,1) = {"
+(17,1,1) = {"
lt
jx
Od
jD
-TC
+ka
yh
-hM
+qp
oV
Hm
Mz
@@ -1379,18 +1378,18 @@ Cg
jx
lt
"}
-(19,1,1) = {"
+(18,1,1) = {"
lt
jx
Od
Od
Od
Od
-NT
-Qg
+DT
+vj
vP
vY
-NT
+DT
Rv
uP
JV
@@ -1400,7 +1399,7 @@ Od
jx
lt
"}
-(20,1,1) = {"
+(19,1,1) = {"
lt
jx
jx
@@ -1408,9 +1407,9 @@ jx
jx
Od
Od
-at
-at
-at
+Qg
+Qg
+Qg
Od
Od
Od
@@ -1421,18 +1420,18 @@ jx
jx
lt
"}
-(21,1,1) = {"
+(20,1,1) = {"
lt
lt
jx
jx
jx
jx
-jx
+hM
lt
lt
lt
-jx
+hM
jx
jx
jx
@@ -1442,7 +1441,7 @@ jx
lt
lt
"}
-(22,1,1) = {"
+(21,1,1) = {"
lt
lt
lt
diff --git a/_maps/shuttles/whiteship_box.dmm b/_maps/shuttles/whiteship_box.dmm
index 48d47820df2..cbfdf87ce09 100644
--- a/_maps/shuttles/whiteship_box.dmm
+++ b/_maps/shuttles/whiteship_box.dmm
@@ -593,7 +593,7 @@
"bs" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/dirt,
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/obj/effect/turf_decal/stripes/line{
dir = 9
},
@@ -622,7 +622,7 @@
"bu" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/dirt,
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/obj/effect/turf_decal/stripes/line{
dir = 5
},
diff --git a/_maps/templates/battlecruiser_starfury.dmm b/_maps/templates/battlecruiser_starfury.dmm
index d3f72900fd4..1e4905ac26e 100644
--- a/_maps/templates/battlecruiser_starfury.dmm
+++ b/_maps/templates/battlecruiser_starfury.dmm
@@ -3885,7 +3885,7 @@
/turf/open/floor/engine,
/area/shuttle/sbc_starfury)
"qQ" = (
-/obj/machinery/atmospherics/components/unary/cryo_cell,
+/obj/machinery/cryo_cell,
/turf/open/floor/plating,
/area/shuttle/sbc_starfury)
"qS" = (
diff --git a/code/__DEFINES/actions.dm b/code/__DEFINES/actions.dm
index 066d2d60c1e..5bc2b161781 100644
--- a/code/__DEFINES/actions.dm
+++ b/code/__DEFINES/actions.dm
@@ -8,6 +8,8 @@
#define AB_CHECK_CONSCIOUS (1<<3)
///Action button checks if user is incapacitated
#define AB_CHECK_INCAPACITATED (1<<4)
+///Action button checks if user is jaunting
+#define AB_CHECK_PHASED (1<<5)
DEFINE_BITFIELD(check_flags, list(
"CHECK IF HANDS BLOCKED" = AB_CHECK_HANDS_BLOCKED,
@@ -15,6 +17,7 @@ DEFINE_BITFIELD(check_flags, list(
"CHECK IF LYING DOWN" = AB_CHECK_LYING,
"CHECK IF CONSCIOUS" = AB_CHECK_CONSCIOUS,
"CHECK IF INCAPACITATED" = AB_CHECK_INCAPACITATED,
+ "CHECK IF TEMPORARILY INCORPOREAL" = AB_CHECK_PHASED,
))
///Action button triggered with right click
diff --git a/code/__DEFINES/ai/ai_blackboard.dm b/code/__DEFINES/ai/ai_blackboard.dm
index 443a51a7eb7..e23a5a12dba 100644
--- a/code/__DEFINES/ai/ai_blackboard.dm
+++ b/code/__DEFINES/ai/ai_blackboard.dm
@@ -8,6 +8,8 @@
#define BB_FOOD_TARGET "bb_food_target"
///Path we should use next time we use the JPS movement datum
#define BB_PATH_TO_USE "BB_path_to_use"
+///How close a mob must be for us to select it as a target, if that is less than how far we can maintain it as a target
+#define BB_AGGRO_RANGE "BB_aggro_range"
///song instrument blackboard, set by instrument subtrees
#define BB_SONG_INSTRUMENT "BB_SONG_INSTRUMENT"
@@ -41,6 +43,8 @@
#define BB_BASIC_MOB_FLEE_TARGET "BB_basic_flee_target"
#define BB_BASIC_MOB_FLEE_TARGET_HIDING_LOCATION "BB_basic_flee_target_hiding_location"
#define BB_FLEE_TARGETTING_DATUM "flee_targetting_datum"
+#define BB_BASIC_MOB_FLEE_DISTANCE "BB_basic_flee_distance"
+#define DEFAULT_BASIC_FLEE_DISTANCE 9
/// Generic key for a non-specific targetted action
#define BB_TARGETTED_ACTION "BB_targetted_action"
diff --git a/code/__DEFINES/ai/monsters.dm b/code/__DEFINES/ai/monsters.dm
index 927f3736832..be9a4be34cd 100644
--- a/code/__DEFINES/ai/monsters.dm
+++ b/code/__DEFINES/ai/monsters.dm
@@ -146,3 +146,10 @@
#define BB_RAPIDSEEDS_ABILITY "rapidseeds_ability"
/// key holds the tray we will beam
#define BB_BEAMABLE_HYDROPLANT_TARGET "beamable_hydroplant_target"
+
+/// Corpse we have consumed
+#define BB_LEGION_CORPSE "legion_corpse"
+/// Things our target recently said
+#define BB_LEGION_RECENT_LINES "legion_recent_lines"
+/// The creator of our legion skull
+#define BB_LEGION_BROOD_CREATOR "legion_brood_creator"
diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm
index e74cd6a58bd..123c60abad2 100644
--- a/code/__DEFINES/antagonists.dm
+++ b/code/__DEFINES/antagonists.dm
@@ -331,8 +331,8 @@ GLOBAL_LIST_INIT(human_invader_antagonists, list(
#define ANTAG_GROUP_PARADOX "Spacetime Aberrations"
-// If this flag is enabled the antagonist datum allows the antagonist to be inducted into a nuclear operative team.
-#define FLAG_ANTAG_CAN_BE_INDUCTED (1 << 0)
+// This flag disables certain checks that presume antagonist datums mean 'baddie'.
+#define FLAG_FAKE_ANTAG (1 << 0)
#define HUNTER_PACK_COPS "Spacepol Fugitive Hunters"
#define HUNTER_PACK_RUSSIAN "Russian Fugitive Hunters"
@@ -365,3 +365,5 @@ GLOBAL_LIST_INIT(human_invader_antagonists, list(
#define BATON_CUFF 2
#define BATON_PROBE 3
#define BATON_MODES 4
+
+#define FREEDOM_IMPLANT_CHARGES 4
diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm
index 25bd59bc8b5..b14fd514b85 100644
--- a/code/__DEFINES/colors.dm
+++ b/code/__DEFINES/colors.dm
@@ -93,6 +93,7 @@
#define COLOR_STRONG_MAGENTA "#B800B8"
#define COLOR_PURPLE "#800080"
#define COLOR_VIOLET "#B900F7"
+#define COLOR_VOID_PURPLE "#53277E"
#define COLOR_STRONG_VIOLET "#6927C5"
#define COLOR_DARK_PURPLE "#551A8B"
diff --git a/code/__DEFINES/cooldowns.dm b/code/__DEFINES/cooldowns.dm
index f486e6a943b..63c1f2fd713 100644
--- a/code/__DEFINES/cooldowns.dm
+++ b/code/__DEFINES/cooldowns.dm
@@ -108,4 +108,6 @@
#define COOLDOWN_RESET(cd_source, cd_index) cd_source.cd_index = 0
+#define COOLDOWN_STARTED(cd_source, cd_index) (cd_source.cd_index != 0)
+
#define COOLDOWN_TIMELEFT(cd_source, cd_index) (max(0, cd_source.cd_index - world.time))
diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm
index dc0293fb274..cd123e2e0b1 100644
--- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm
+++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm
@@ -11,17 +11,19 @@
#define COMSIG_ATOM_EXAMINE "atom_examine"
///from base of atom/get_examine_name(): (/mob, list/overrides)
#define COMSIG_ATOM_GET_EXAMINE_NAME "atom_examine_name"
-///from base of atom/examine(): (/mob, list/examine_text, can_see_inside)
-#define COMSIG_ATOM_REAGENT_EXAMINE "atom_reagent_examine"
- /// Stop the generic reagent examine text
- #define STOP_GENERIC_REAGENT_EXAMINE (1<<0)
-///from base of atom/examine_more(): (/mob)
-#define COMSIG_ATOM_EXAMINE_MORE "atom_examine_more"
//Positions for overrides list
#define EXAMINE_POSITION_ARTICLE (1<<0)
#define EXAMINE_POSITION_BEFORE (1<<1)
//End positions
#define COMPONENT_EXNAME_CHANGED (1<<0)
+///from base of atom/examine(): (/mob, list/examine_text, can_see_inside)
+#define COMSIG_ATOM_REAGENT_EXAMINE "atom_reagent_examine"
+ /// Stop the generic reagent examine text
+ #define STOP_GENERIC_REAGENT_EXAMINE (1<<0)
+///from base of atom/examine_more(): (/mob, examine_list)
+#define COMSIG_ATOM_EXAMINE_MORE "atom_examine_more"
+/// from atom/examine_more(): (/atom/examining, examine_list)
+#define COMSIG_MOB_EXAMINING_MORE "mob_examining_more"
///from base of [/atom/proc/update_appearance]: (updates)
#define COMSIG_ATOM_UPDATE_APPEARANCE "atom_update_appearance"
/// If returned from [COMSIG_ATOM_UPDATE_APPEARANCE] it prevents the atom from updating its name.
diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm
index 19286859e9e..4521360d039 100644
--- a/code/__DEFINES/dcs/signals/signals_object.dm
+++ b/code/__DEFINES/dcs/signals/signals_object.dm
@@ -33,6 +33,8 @@
#define COMSIG_MACHINERY_STOP_PROCESSING_AIR "stop_processing_air"
///from /obj/machinery/RefreshParts: ()
#define COMSIG_MACHINERY_REFRESH_PARTS "machine_refresh_parts"
+///from /obj/machinery/default_change_direction_wrench: (mob/user, obj/item/wrench)
+#define COMSIG_MACHINERY_DEFAULT_ROTATE_WRENCH "machinery_default_rotate_wrench"
///from /obj/machinery/can_interact(mob/user): Called on user when attempting to interact with a machine (obj/machinery/machine)
#define COMSIG_TRY_USE_MACHINE "try_use_machine"
@@ -58,9 +60,9 @@
#define COMSIG_SUPERMATTER_DELAM_ALARM "sm_delam_alarm"
-// /obj/machinery/atmospherics/components/unary/cryo_cell signals
+// /obj/machinery/cryo_cell signals
-/// from /obj/machinery/atmospherics/components/unary/cryo_cell/set_on(bool): (on)
+/// from /obj/machinery/cryo_cell/set_on(bool): (on)
#define COMSIG_CRYO_SET_ON "cryo_set_on"
/// from /obj/proc/unfreeze()
diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm
index c76276c019d..f2f511c791b 100644
--- a/code/__DEFINES/inventory.dm
+++ b/code/__DEFINES/inventory.dm
@@ -170,6 +170,7 @@
#define MASKCOVERSMOUTH (1<<3) // on other items, these are just for mask/head
#define HEADCOVERSMOUTH (1<<4)
#define PEPPERPROOF (1<<5) //protects against pepperspray
+#define EARS_COVERED (1<<6)
#define TINT_DARKENED 2 //Threshold of tint level to apply weld mask overlay
#define TINT_BLIND 3 //Threshold of tint level to obscure vision fully
diff --git a/code/__DEFINES/magic.dm b/code/__DEFINES/magic.dm
index 34ec4b6659b..ecc470c04e9 100644
--- a/code/__DEFINES/magic.dm
+++ b/code/__DEFINES/magic.dm
@@ -50,8 +50,7 @@
/// Whether the spell can be cast by mobs who are brains / mmis.
/// When applying, bear in mind most spells will not function for brains out of the box.
#define SPELL_CASTABLE_AS_BRAIN (1 << 2)
-/// Whether the spell can be cast while phased, such as blood crawling, ethereal jaunting or using rod form.
-#define SPELL_CASTABLE_WHILE_PHASED (1 << 3)
+
/// Whether the spell can be cast while the user has antimagic on them that corresponds to the spell's own antimagic flags.
#define SPELL_REQUIRES_NO_ANTIMAGIC (1 << 4)
/// Whether the spell requires being on the station z-level to be cast.
@@ -66,7 +65,6 @@
DEFINE_BITFIELD(spell_requirements, list(
"SPELL_CASTABLE_AS_BRAIN" = SPELL_CASTABLE_AS_BRAIN,
- "SPELL_CASTABLE_WHILE_PHASED" = SPELL_CASTABLE_WHILE_PHASED,
"SPELL_CASTABLE_WITHOUT_INVOCATION" = SPELL_CASTABLE_WITHOUT_INVOCATION,
"SPELL_REQUIRES_HUMAN" = SPELL_REQUIRES_HUMAN,
"SPELL_REQUIRES_MIME_VOW" = SPELL_REQUIRES_MIME_VOW,
diff --git a/code/__DEFINES/maths.dm b/code/__DEFINES/maths.dm
index eb1b2ecce51..1260e3daf03 100644
--- a/code/__DEFINES/maths.dm
+++ b/code/__DEFINES/maths.dm
@@ -254,3 +254,6 @@
/// Returns a random decimal between x and y.
#define RANDOM_DECIMAL(x, y) LERP((x), (y), rand())
+
+#define SI_COEFFICIENT "coefficient"
+#define SI_UNIT "unit"
diff --git a/code/__DEFINES/mood.dm b/code/__DEFINES/mood.dm
new file mode 100644
index 00000000000..161f253b04c
--- /dev/null
+++ b/code/__DEFINES/mood.dm
@@ -0,0 +1 @@
+#define MOOD_CATEGORY_LEGION_CORE "regenerative core"
diff --git a/code/__DEFINES/robots.dm b/code/__DEFINES/robots.dm
index 7f7961e05be..4d32c136331 100644
--- a/code/__DEFINES/robots.dm
+++ b/code/__DEFINES/robots.dm
@@ -1,4 +1,4 @@
-/** AI defines */
+// AI defines
#define DEFAULT_AI_LAWID "default"
#define LAW_ZEROTH "zeroth"
@@ -27,7 +27,10 @@
///Malfunctioning AI hijacking mecha
#define AI_MECH_HACK 3
-/** Cyborg defines */
+// Cyborg defines
+
+/// If an item does this or more throwing damage it will slow a borg down on hit
+#define CYBORG_THROW_SLOWDOWN_THRESHOLD 10
/// Special value to reset cyborg's lamp_cooldown
#define BORG_LAMP_CD_RESET -1
diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm
index 3caed7a0622..d95973e3fdb 100644
--- a/code/__DEFINES/sound.dm
+++ b/code/__DEFINES/sound.dm
@@ -150,7 +150,6 @@
#define ANNOUNCER_ICARUS "announcer_icarus"
#define ANNOUNCER_NRI_RAIDERS "announcer_nri_raiders"
#define ANNOUNCER_OUTBREAK6 "announcer_outbreak6"
-#define ANNOUNCER_FUNGI "announcer_fungi"
#define ANNOUNCER_DEPARTMENTAL "announcer_departmental"
#define ANNOUNCER_SHUTTLE "announcer_shuttle"
//SKYRAT EDIT END
@@ -199,7 +198,6 @@ GLOBAL_LIST_INIT(announcer_keys, list(
ANNOUNCER_ICARUS,
ANNOUNCER_NRI_RAIDERS,
ANNOUNCER_OUTBREAK6,
- ANNOUNCER_FUNGI,
//SKYRAT EDIT END
))
diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm
index 50b33eb4c75..ea182b4088f 100644
--- a/code/__DEFINES/status_effects.dm
+++ b/code/__DEFINES/status_effects.dm
@@ -37,6 +37,7 @@
#define STASIS_CHEMICAL_EFFECT "stasis_chemical"
#define STASIS_SHAPECHANGE_EFFECT "stasis_shapechange"
#define STASIS_ADMIN "stasis_admin"
+#define STASIS_LEGION_EATEN "stasis_eaten"
/// Causes the mob to become blind via the passed source
#define become_blind(source) apply_status_effect(/datum/status_effect/grouped/blindness, source)
diff --git a/code/__DEFINES/supermatter.dm b/code/__DEFINES/supermatter.dm
index bac35207fb5..5eab41fcdf9 100644
--- a/code/__DEFINES/supermatter.dm
+++ b/code/__DEFINES/supermatter.dm
@@ -28,6 +28,12 @@
#define MATTER_POWER_CONVERSION 10 //Crystal converts 1/this value of stored matter into energy.
+/// The internal energy gain coefficient.
+#define GAS_HEAT_POWER_SCALING_COEFFICIENT (1/6)
+
+/// The base zap power transmission of the supermatter crystal in W/MeV.
+#define BASE_POWER_TRANSMISSION_RATE 1040
+
//These would be what you would get at point blank, decreases with distance
#define DETONATION_HALLUCINATION (20 MINUTES)
@@ -165,9 +171,9 @@
#define SM_TEMP_LIMIT_LOW_MOLES "Low Moles Heat Resistance"
/// How much we are multiplying our zap energy.
-#define SM_ZAP_BASE "Base Zap Multiplier"
+#define SM_ZAP_BASE "Base Zap Transmission"
/// How much we are multiplying our zap energy because of gas factors.
-#define SM_ZAP_GAS "Gas Zap Multiplier"
+#define SM_ZAP_GAS "Gas Zap Transmission Modifier"
/// Delamination types.
#define CASCADE_DELAMINATION "cascade"
#define SINGULARITY_DELAMINATION "singularity"
diff --git a/code/__DEFINES/tts.dm b/code/__DEFINES/tts.dm
index cca1b5db000..fd88016408c 100644
--- a/code/__DEFINES/tts.dm
+++ b/code/__DEFINES/tts.dm
@@ -4,3 +4,7 @@
#define TTS_SOUND_ENABLED "Enabled"
///TTS preference is set to only play blips of a sound, rather than speech.
#define TTS_SOUND_BLIPS "Blips Only"
+///TTS filter to activate start/stop radio clicks on speech.
+#define TTS_FILTER_RADIO "radio"
+///TTS filter to activate a silicon effect on speech.
+#define TTS_FILTER_SILICON "silicon"
diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm
index 07239ca07c5..1cc9025b821 100644
--- a/code/__DEFINES/vv.dm
+++ b/code/__DEFINES/vv.dm
@@ -114,6 +114,8 @@
// /mob
#define VV_HK_GIB "gib"
+#define VV_HK_GIVE_MOB_ACTION "give_mob_action"
+#define VV_HK_REMOVE_MOB_ACTION "remove_mob_action"
#define VV_HK_GIVE_SPELL "give_spell"
#define VV_HK_REMOVE_SPELL "remove_spell"
#define VV_HK_GIVE_DISEASE "give_disease"
@@ -149,6 +151,7 @@
#define VV_HK_MOD_QUIRKS "quirkmod"
#define VV_HK_SET_SPECIES "setspecies"
#define VV_HK_PURRBATION "purrbation"
+#define VV_HK_APPLY_DNA_INFUSION "apply_dna_infusion"
// misc
#define VV_HK_SPACEVINE_PURGE "spacevine_purge"
diff --git a/code/__DEFINES/~skyrat_defines/nifsofts.dm b/code/__DEFINES/~skyrat_defines/nifsofts.dm
index ebf138343c0..f3852414f60 100644
--- a/code/__DEFINES/~skyrat_defines/nifsofts.dm
+++ b/code/__DEFINES/~skyrat_defines/nifsofts.dm
@@ -4,3 +4,4 @@
#define NIFSOFT_CATEGORY_COSMETIC "Cosmetic"
#define NIFSOFT_CATEGORY_UTILITY "Utility"
#define NIFSOFT_CATEGORY_FUN "Fun"
+#define NIFSOFT_CATEGORY_INFORMATION "Information"
diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm
index 34512b95952..fb1603d650d 100644
--- a/code/__HELPERS/_lists.dm
+++ b/code/__HELPERS/_lists.dm
@@ -408,6 +408,17 @@
list_to_clear -= new_list
return list_to_clear.len < start_len
+/**
+ * Removes any empty weakrefs from the list
+ * Returns TRUE if the list had empty refs, FALSE otherwise
+**/
+/proc/list_clear_empty_weakrefs(list/list_to_clear)
+ var/start_len = list_to_clear.len
+ for(var/datum/weakref/entry in list_to_clear)
+ if(!entry.resolve())
+ list_to_clear -= entry
+ return list_to_clear.len < start_len
+
/*
* Returns list containing all the entries from first list that are not present in second.
* If skiprep = 1, repeated elements are treated as one.
diff --git a/code/__HELPERS/maths.dm b/code/__HELPERS/maths.dm
index 6cda3466949..116fb34fad5 100644
--- a/code/__HELPERS/maths.dm
+++ b/code/__HELPERS/maths.dm
@@ -119,25 +119,48 @@
dx -= 1
return perimeter
-///Format a power value in W, kW, MW, or GW.
+/**
+ * Formats a number into a list representing the si unit.
+ * Access the coefficient with [SI_COEFFICIENT], and access the unit with [SI_UNIT].
+ *
+ * Supports SI exponents between 1e-15 to 1e15, but properly handles numbers outside that range as well.
+ * Arguments:
+ * * value - The number to convert to text. Can be positive or negative.
+ * * unit - The base unit of the number, such as "Pa" or "W".
+ * * maxdecimals - Maximum amount of decimals to display for the final number. Defaults to 1.
+ * Returns: [SI_COEFFICIENT = si unit coefficient, SI_UNIT = prefixed si unit.]
+ */
+/proc/siunit_isolated(value, unit, maxdecimals=1)
+ var/static/list/prefixes = list("f","p","n","μ","m","","k","M","G","T","P")
+
+ // We don't have prefixes beyond this point
+ // and this also captures value = 0 which you can't compute the logarithm for
+ // and also byond numbers are floats and doesn't have much precision beyond this point anyway
+ if(abs(value) <= 1e-18)
+ . = list(SI_COEFFICIENT = 0, SI_UNIT = " [unit]")
+ return
+
+ var/exponent = clamp(log(10, abs(value)), -15, 15) // Calculate the exponent and clamp it so we don't go outside the prefix list bounds
+ var/divider = 10 ** (round(exponent / 3) * 3) // Rounds the exponent to nearest SI unit and power it back to the full form
+ var/coefficient = round(value / divider, 10 ** -maxdecimals) // Calculate the coefficient and round it to desired decimals
+ var/prefix_index = round(exponent / 3) + 6 // Calculate the index in the prefixes list for this exponent
+
+ // An edge case which happens if we round 999.9 to 0 decimals for example, which gets rounded to 1000
+ // In that case, we manually swap up to the next prefix if there is one available
+ if(coefficient >= 1000 && prefix_index < 11)
+ coefficient /= 1e3
+ prefix_index++
+
+ var/prefix = prefixes[prefix_index]
+ . = list(SI_COEFFICIENT = coefficient, SI_UNIT = " [prefix][unit]")
+
+///Format a power value in prefixed watts.
/proc/display_power(powerused)
- if(powerused < 1000) //Less than a kW
- return "[powerused] W"
- else if(powerused < 1000000) //Less than a MW
- return "[round((powerused * 0.001),0.01)] kW"
- else if(powerused < 1000000000) //Less than a GW
- return "[round((powerused * 0.000001),0.001)] MW"
- return "[round((powerused * 0.000000001),0.0001)] GW"
-
-///Format an energy value in J, kJ, MJ, or GJ. 1W = 1J/s.
+ return siunit(powerused, "W", 3)
+
+///Format an energy value in prefixed joules.
/proc/display_joules(units)
- if (units < 1000) // Less than a kJ
- return "[round(units, 0.1)] J"
- else if (units < 1000000) // Less than a MJ
- return "[round(units * 0.001, 0.01)] kJ"
- else if (units < 1000000000) // Less than a GJ
- return "[round(units * 0.000001, 0.001)] MJ"
- return "[round(units * 0.000000001, 0.0001)] GJ"
+ return siunit(units, "J", 3)
/proc/joules_to_energy(joules)
return joules * (1 SECONDS) / SSmachines.wait
diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm
index f75e6770207..91406650d20 100644
--- a/code/__HELPERS/text.dm
+++ b/code/__HELPERS/text.dm
@@ -191,7 +191,7 @@
// 0 .. 9
if(48 to 57) //Numbers
- if(last_char_group == NO_CHARS_DETECTED || !allow_numbers) //suppress at start of string
+ if(!allow_numbers) //allow name to start with number if AI/Borg
if(strict)
return
continue
@@ -1048,27 +1048,8 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
* * For pressure conversion, use proc/siunit_pressure() below
*/
/proc/siunit(value, unit, maxdecimals=1)
- var/static/list/prefixes = list("f","p","n","μ","m","","k","M","G","T","P")
-
- // We don't have prefixes beyond this point
- // and this also captures value = 0 which you can't compute the logarithm for
- // and also byond numbers are floats and doesn't have much precision beyond this point anyway
- if(abs(value) <= 1e-18)
- return "0 [unit]"
-
- var/exponent = clamp(log(10, abs(value)), -15, 15) // Calculate the exponent and clamp it so we don't go outside the prefix list bounds
- var/divider = 10 ** (round(exponent / 3) * 3) // Rounds the exponent to nearest SI unit and power it back to the full form
- var/coefficient = round(value / divider, 10 ** -maxdecimals) // Calculate the coefficient and round it to desired decimals
- var/prefix_index = round(exponent / 3) + 6 // Calculate the index in the prefixes list for this exponent
-
- // An edge case which happens if we round 999.9 to 0 decimals for example, which gets rounded to 1000
- // In that case, we manually swap up to the next prefix if there is one available
- if(coefficient >= 1000 && prefix_index < 11)
- coefficient /= 1e3
- prefix_index++
-
- var/prefix = prefixes[prefix_index]
- return "[coefficient] [prefix][unit]"
+ var/si_isolated = siunit_isolated(value, unit, maxdecimals)
+ return "[si_isolated[SI_COEFFICIENT]][si_isolated[SI_UNIT]]"
/** The game code never uses Pa, but kPa, since 1 Pa is too small to reasonably handle
diff --git a/code/_globalvars/lists/maintenance_loot.dm b/code/_globalvars/lists/maintenance_loot.dm
index d16c466f9dc..aa84927af03 100644
--- a/code/_globalvars/lists/maintenance_loot.dm
+++ b/code/_globalvars/lists/maintenance_loot.dm
@@ -347,6 +347,7 @@ GLOBAL_LIST_INIT(rarity_loot, list(//rare: really good items
/obj/item/book/granter/crafting_recipe/dusting/laser_musket_prime = 1,
/obj/item/book/granter/sign_language = 1,
/obj/item/disk/nuclear/fake = 1,
+ /obj/item/disk/surgery/advanced_plastic_surgery = 1,
/obj/item/skillchip/brainwashing = 1,
/obj/item/tattoo_kit = 1,
/obj/item/folder/ancient_paperwork = 1,
diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm
index 6f7d9c987f7..f87896e4521 100644
--- a/code/_globalvars/lists/mobs.dm
+++ b/code/_globalvars/lists/mobs.dm
@@ -113,7 +113,7 @@ GLOBAL_LIST_INIT(construct_radial_images, list(
/proc/get_crewmember_minds()
var/list/minds = list()
for(var/datum/record/locked/target in GLOB.manifest.locked)
- var/datum/mind/mind = target.mind_ref
+ var/datum/mind/mind = target.mind_ref.resolve()
if(mind)
minds += mind
return minds
diff --git a/code/_globalvars/lists/quirks.dm b/code/_globalvars/lists/quirks.dm
index 9d936c18e56..f907206a30c 100644
--- a/code/_globalvars/lists/quirks.dm
+++ b/code/_globalvars/lists/quirks.dm
@@ -11,3 +11,11 @@ GLOBAL_LIST_INIT(nearsighted_glasses, list(
"Modern" = /obj/item/clothing/glasses/betterunshit, // SKYRAT ADD
))
+
+///Options for the prothetic limb quirk to choose from
+GLOBAL_LIST_INIT(limb_choice, list(
+ "Left Arm" = /obj/item/bodypart/arm/left/robot/surplus,
+ "Right Arm" = /obj/item/bodypart/arm/right/robot/surplus,
+ "Left Leg" = /obj/item/bodypart/leg/left/robot/surplus,
+ "Right Leg" = /obj/item/bodypart/leg/right/robot/surplus,
+))
diff --git a/code/_globalvars/phobias.dm b/code/_globalvars/phobias.dm
index a6cb2dedb32..a913410214d 100644
--- a/code/_globalvars/phobias.dm
+++ b/code/_globalvars/phobias.dm
@@ -88,7 +88,7 @@ GLOBAL_LIST_INIT(phobia_mobs, list(
"security" = typecacheof(list(/mob/living/simple_animal/bot/secbot)),
"spiders" = typecacheof(list(/mob/living/basic/spider/giant)),
"skeletons" = typecacheof(list(/mob/living/simple_animal/hostile/skeleton)),
- "snakes" = typecacheof(list(/mob/living/simple_animal/hostile/retaliate/snake)),
+ "snakes" = typecacheof(list(/mob/living/basic/snake)),
"the supernatural" = typecacheof(list(
/mob/dead/observer,
/mob/living/basic/bat,
@@ -331,7 +331,7 @@ GLOBAL_LIST_INIT(phobia_objs, list(
/obj/item/storage/pill_bottle,
/obj/item/surgical_drapes,
/obj/item/surgicaldrill,
- /obj/machinery/atmospherics/components/unary/cryo_cell,
+ /obj/machinery/cryo_cell,
/obj/machinery/dna_scannernew,
/obj/machinery/door/airlock/medical,
/obj/machinery/sleeper,
diff --git a/code/controllers/configuration/entries/jobs.dm b/code/controllers/configuration/entries/jobs.dm
index 99a3ab7a701..06563e01a8e 100644
--- a/code/controllers/configuration/entries/jobs.dm
+++ b/code/controllers/configuration/entries/jobs.dm
@@ -9,7 +9,7 @@
return returnable_list
/// Sets all of the job datum configurable values to what they've been set to in the config file, jobconfig.toml.
-/datum/controller/subsystem/job/proc/load_jobs_from_config()
+/datum/controller/subsystem/job/proc/load_jobs_from_config(silent = FALSE)
if(!length(job_config_datum_singletons))
stack_trace("SSjob tried to load jobs from config, but the config singletons were not initialized! Likely tried to load jobs before SSjob was initialized.")
return
@@ -25,7 +25,8 @@
var/job_key = occupation.config_tag
if(!job_config[job_key]) // Job isn't listed, skip it.
// List both job_title and job_key in case they de-sync over time.
- message_admins(span_notice("[occupation.title] (with config key [job_key]) is missing from jobconfig.toml! Using codebase defaults."))
+ if(!silent)
+ message_admins(span_notice("[occupation.title] (with config key [job_key]) is missing from jobconfig.toml! Using codebase defaults."))
continue
for(var/config_datum_key in job_config_datum_singletons)
diff --git a/code/controllers/subsystem/economy.dm b/code/controllers/subsystem/economy.dm
index b8e1ab9e772..e396bcb8445 100644
--- a/code/controllers/subsystem/economy.dm
+++ b/code/controllers/subsystem/economy.dm
@@ -204,9 +204,9 @@ SUBSYSTEM_DEF(economy)
CRASH("Track purchases was missing an argument! (Account, Price, or Vendor.)")
audit_log += list(list(
- "account" = account.account_holder,
+ "account" = "[account.account_holder]",
"cost" = price_to_use,
- "vendor" = vendor,
+ "vendor" = "[vendor]",
))
/**
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index 5c957445526..976b4bab249 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -305,6 +305,10 @@ SUBSYSTEM_DEF(job)
player.mind.special_role = null
SetupOccupations()
unassigned = list()
+ if(CONFIG_GET(flag/load_jobs_from_txt))
+ // Any errors with the configs has already been said, we don't need to repeat them here.
+ load_jobs_from_config(silent = TRUE)
+ set_overflow_role(overflow_role)
return
diff --git a/code/controllers/subsystem/radiation.dm b/code/controllers/subsystem/radiation.dm
index b2b3d1926dd..d52fe83856a 100644
--- a/code/controllers/subsystem/radiation.dm
+++ b/code/controllers/subsystem/radiation.dm
@@ -135,7 +135,7 @@ SUBSYSTEM_DEF(radiation)
for (var/obj/item/bodypart/limb as anything in human.bodyparts)
var/protected = FALSE
- for (var/obj/item/clothing as anything in human.clothingonpart(limb))
+ for (var/obj/item/clothing as anything in human.get_clothing_on_part(limb))
if (HAS_TRAIT(clothing, TRAIT_RADIATION_PROTECTED_CLOTHING))
protected = TRUE
break
diff --git a/code/controllers/subsystem/tts.dm b/code/controllers/subsystem/tts.dm
index 712168b5027..b9cb85ea78a 100644
--- a/code/controllers/subsystem/tts.dm
+++ b/code/controllers/subsystem/tts.dm
@@ -261,7 +261,7 @@ SUBSYSTEM_DEF(tts)
#undef TTS_ARBRITRARY_DELAY
-/datum/controller/subsystem/tts/proc/queue_tts_message(datum/target, message, datum/language/language, speaker, filter, list/listeners, local = FALSE, message_range = 7, volume_offset = 0, pitch = 0, silicon = "")
+/datum/controller/subsystem/tts/proc/queue_tts_message(datum/target, message, datum/language/language, speaker, filter, list/listeners, local = FALSE, message_range = 7, volume_offset = 0, pitch = 0, special_filters = "")
if(!tts_enabled)
return
@@ -277,7 +277,7 @@ SUBSYSTEM_DEF(tts)
var/shell_scrubbed_input = tts_speech_filter(message)
shell_scrubbed_input = copytext(shell_scrubbed_input, 1, 300)
- var/identifier = "[sha1(speaker + filter + num2text(pitch) + num2text(silicon) + shell_scrubbed_input)].[world.time]"
+ var/identifier = "[sha1(speaker + filter + num2text(pitch) + special_filters + shell_scrubbed_input)].[world.time]"
if(!(speaker in available_speakers))
return
@@ -288,9 +288,9 @@ SUBSYSTEM_DEF(tts)
var/datum/http_request/request_blips = new()
var/file_name = "tmp/tts/[identifier].ogg"
var/file_name_blips = "tmp/tts/[identifier]_blips.ogg"
- request.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/tts_http_url)]/tts?voice=[speaker]&identifier=[identifier]&filter=[url_encode(filter)]&pitch=[pitch]&silicon=[silicon]", json_encode(list("text" = shell_scrubbed_input)), headers, file_name)
- request_blips.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/tts_http_url)]/tts-blips?voice=[speaker]&identifier=[identifier]&filter=[url_encode(filter)]&pitch=[pitch]&silicon=[silicon]", json_encode(list("text" = shell_scrubbed_input)), headers, file_name_blips)
- var/datum/tts_request/current_request = new /datum/tts_request(identifier, request, request_blips, shell_scrubbed_input, target, local, language, message_range, volume_offset, listeners, pitch, silicon)
+ request.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/tts_http_url)]/tts?voice=[speaker]&identifier=[identifier]&filter=[url_encode(filter)]&pitch=[pitch]&special_filters=[url_encode(special_filters)]", json_encode(list("text" = shell_scrubbed_input)), headers, file_name)
+ request_blips.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/tts_http_url)]/tts-blips?voice=[speaker]&identifier=[identifier]&filter=[url_encode(filter)]&pitch=[pitch]&special_filters=[url_encode(special_filters)]", json_encode(list("text" = shell_scrubbed_input)), headers, file_name_blips)
+ var/datum/tts_request/current_request = new /datum/tts_request(identifier, request, request_blips, shell_scrubbed_input, target, local, language, message_range, volume_offset, listeners, pitch)
var/list/player_queued_tts_messages = queued_tts_messages[target]
if(!player_queued_tts_messages)
player_queued_tts_messages = list()
@@ -342,8 +342,6 @@ SUBSYSTEM_DEF(tts)
var/use_blips = FALSE
/// What's the pitch adjustment?
var/pitch = 0
- /// Are we using the silicon vocal effect on this?
- var/silicon = ""
/datum/tts_request/New(identifier, datum/http_request/request, datum/http_request/request_blips, message, target, local, datum/language/language, message_range, volume_offset, list/listeners, pitch)
diff --git a/code/datums/actions/action.dm b/code/datums/actions/action.dm
index b43220fb7d4..843998ff50e 100644
--- a/code/datums/actions/action.dm
+++ b/code/datums/actions/action.dm
@@ -96,13 +96,15 @@
if(check_flags & AB_CHECK_CONSCIOUS)
RegisterSignal(owner, COMSIG_MOB_STATCHANGE, PROC_REF(update_status_on_signal))
if(check_flags & AB_CHECK_INCAPACITATED)
- RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_INCAPACITATED), PROC_REF(update_status_on_signal))
+ RegisterSignals(owner, list(SIGNAL_ADDTRAIT(TRAIT_INCAPACITATED), SIGNAL_REMOVETRAIT(TRAIT_INCAPACITATED)), PROC_REF(update_status_on_signal))
if(check_flags & AB_CHECK_IMMOBILE)
- RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_IMMOBILIZED), PROC_REF(update_status_on_signal))
+ RegisterSignals(owner, list(SIGNAL_ADDTRAIT(TRAIT_IMMOBILIZED), SIGNAL_REMOVETRAIT(TRAIT_IMMOBILIZED)), PROC_REF(update_status_on_signal))
if(check_flags & AB_CHECK_HANDS_BLOCKED)
- RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_HANDS_BLOCKED), PROC_REF(update_status_on_signal))
+ RegisterSignals(owner, list(SIGNAL_ADDTRAIT(TRAIT_HANDS_BLOCKED), SIGNAL_REMOVETRAIT(TRAIT_HANDS_BLOCKED)), PROC_REF(update_status_on_signal))
if(check_flags & AB_CHECK_LYING)
RegisterSignal(owner, COMSIG_LIVING_SET_BODY_POSITION, PROC_REF(update_status_on_signal))
+ if(check_flags & AB_CHECK_PHASED)
+ RegisterSignals(owner, list(SIGNAL_ADDTRAIT(TRAIT_MAGICALLY_PHASED), SIGNAL_REMOVETRAIT(TRAIT_MAGICALLY_PHASED)), PROC_REF(update_status_on_signal))
if(owner_has_control)
GiveAction(grant_to)
@@ -130,6 +132,11 @@
SIGNAL_ADDTRAIT(TRAIT_HANDS_BLOCKED),
SIGNAL_ADDTRAIT(TRAIT_IMMOBILIZED),
SIGNAL_ADDTRAIT(TRAIT_INCAPACITATED),
+ SIGNAL_ADDTRAIT(TRAIT_MAGICALLY_PHASED),
+ SIGNAL_REMOVETRAIT(TRAIT_HANDS_BLOCKED),
+ SIGNAL_REMOVETRAIT(TRAIT_IMMOBILIZED),
+ SIGNAL_REMOVETRAIT(TRAIT_INCAPACITATED),
+ SIGNAL_REMOVETRAIT(TRAIT_MAGICALLY_PHASED),
))
if(target == owner)
@@ -174,6 +181,10 @@
if (feedback)
owner.balloon_alert(owner, "unconscious!")
return FALSE
+ if((check_flags & AB_CHECK_PHASED) && HAS_TRAIT(owner, TRAIT_MAGICALLY_PHASED))
+ if (feedback)
+ owner.balloon_alert(owner, "incorporeal!")
+ return FALSE
return TRUE
/// Builds / updates all buttons we have shared or given out
diff --git a/code/datums/actions/mobs/charge.dm b/code/datums/actions/mobs/charge.dm
index 2ae576f5e61..7fb56209777 100644
--- a/code/datums/actions/mobs/charge.dm
+++ b/code/datums/actions/mobs/charge.dm
@@ -51,6 +51,7 @@
RegisterSignal(charger, COMSIG_MOVABLE_BUMP, PROC_REF(on_bump), TRUE)
RegisterSignal(charger, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(on_move), TRUE)
RegisterSignal(charger, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved), TRUE)
+ RegisterSignal(charger, COMSIG_LIVING_DEATH, PROC_REF(charge_end))
charger.setDir(dir)
do_charge_indicator(charger, target)
@@ -80,10 +81,13 @@
SIGNAL_HANDLER
actively_moving = FALSE
-/datum/action/cooldown/mob_cooldown/charge/proc/charge_end(datum/move_loop/source)
+/datum/action/cooldown/mob_cooldown/charge/proc/charge_end(datum/source)
SIGNAL_HANDLER
- var/atom/movable/charger = source.moving
- UnregisterSignal(charger, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOVABLE_MOVED))
+ var/atom/movable/charger = source
+ if(istype(source, /datum/move_loop))
+ var/datum/move_loop/move_loop_source = source
+ charger = move_loop_source.moving
+ UnregisterSignal(charger, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOVABLE_MOVED, COMSIG_LIVING_DEATH))
SEND_SIGNAL(owner, COMSIG_FINISHED_CHARGE)
actively_moving = FALSE
charging -= charger
diff --git a/code/datums/actions/mobs/open_mob_commands.dm b/code/datums/actions/mobs/open_mob_commands.dm
index 008e7c4dc1b..e7ffd104eff 100644
--- a/code/datums/actions/mobs/open_mob_commands.dm
+++ b/code/datums/actions/mobs/open_mob_commands.dm
@@ -5,6 +5,7 @@
overlay_icon_state = "bg_heretic_border"
button_icon = 'icons/mob/actions/actions_ecult.dmi'
button_icon_state = "stargazer_menu"
+ check_flags = AB_CHECK_CONSCIOUS | AB_CHECK_INCAPACITATED | AB_CHECK_PHASED
/// Weakref for storing our stargazer
var/datum/weakref/our_mob
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm
index 6683fb02f93..91ba7ec4894 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm
@@ -51,6 +51,8 @@
required_distance = 3
/// range we will try chasing the target before giving up
var/chase_range = 9
+ ///do we care about avoiding friendly fire?
+ var/avoid_friendly_fire = FALSE
/datum/ai_behavior/basic_ranged_attack/setup(datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
. = ..()
@@ -75,6 +77,10 @@
if(!can_see(basic_mob, final_target, required_distance))
return
+ if(avoid_friendly_fire && check_friendly_in_path(basic_mob, target, targetting_datum))
+ adjust_position(basic_mob, target)
+ return ..()
+
controller.set_blackboard_key(hiding_location_key, hiding_target)
basic_mob.RangedAttack(final_target)
return ..() //only start the cooldown when the shot is shot
@@ -83,3 +89,52 @@
. = ..()
if(!succeeded)
controller.clear_blackboard_key(target_key)
+
+/datum/ai_behavior/basic_ranged_attack/proc/check_friendly_in_path(mob/living/source, atom/target, datum/targetting_datum/targetting_datum)
+ var/list/turfs_list = calculate_trajectory(source, target)
+ for(var/turf/possible_turf as anything in turfs_list)
+
+ for(var/mob/living/potential_friend in possible_turf)
+ if(!targetting_datum.can_attack(source, potential_friend))
+ return TRUE
+
+ return FALSE
+
+/datum/ai_behavior/basic_ranged_attack/proc/adjust_position(mob/living/living_pawn, atom/target)
+ var/turf/our_turf = get_turf(living_pawn)
+ var/list/possible_turfs = list()
+
+ for(var/direction in GLOB.alldirs)
+ var/turf/target_turf = get_step(our_turf, direction)
+ if(isnull(target_turf))
+ continue
+ if(target_turf.is_blocked_turf() || get_dist(target_turf, target) > get_dist(living_pawn, target))
+ continue
+ possible_turfs += target_turf
+
+ if(!length(possible_turfs))
+ return
+ var/turf/picked_turf = get_closest_atom(/turf, possible_turfs, target)
+ step(living_pawn, get_dir(living_pawn, picked_turf))
+
+/datum/ai_behavior/basic_ranged_attack/proc/calculate_trajectory(mob/living/source , atom/target)
+ var/list/turf_list = get_line(source, target)
+ var/list_length = length(turf_list) - 1
+ for(var/i in 1 to list_length)
+ var/turf/current_turf = turf_list[i]
+ var/turf/next_turf = turf_list[i+1]
+ var/direction_to_turf = get_dir(current_turf, next_turf)
+ if(!ISDIAGONALDIR(direction_to_turf))
+ continue
+
+ for(var/cardinal_direction in GLOB.cardinals)
+ if(cardinal_direction & direction_to_turf)
+ turf_list += get_step(current_turf, cardinal_direction)
+
+ turf_list -= get_turf(source)
+ turf_list -= get_turf(target)
+
+ return turf_list
+
+/datum/ai_behavior/basic_ranged_attack/avoid_friendly_fire
+ avoid_friendly_fire = TRUE
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm
index 486f9a0fdb2..bd86260ee89 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm
@@ -4,7 +4,7 @@
action_cooldown = 0
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_MOVE_AND_PERFORM | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
/// How far do we try to run? Further makes for smoother running, but potentially weirder pathfinding
- var/run_distance = 9
+ var/run_distance = DEFAULT_BASIC_FLEE_DISTANCE
/// Clear target if we finish the action unsuccessfully
var/clear_failed_targets = TRUE
@@ -12,6 +12,7 @@
var/atom/target = controller.blackboard[hiding_location_key] || controller.blackboard[target_key]
if(QDELETED(target))
return FALSE
+ run_distance = controller.blackboard[BB_BASIC_MOB_FLEE_DISTANCE] || initial(run_distance)
if(!plot_path_away_from(controller, target))
return FALSE
return ..()
@@ -21,13 +22,12 @@
if (!controller.blackboard[BB_BASIC_MOB_FLEEING])
return
var/atom/target = controller.blackboard[hiding_location_key] || controller.blackboard[target_key]
- var/escaped = QDELETED(target) || !can_see(controller.pawn, target, run_distance) // If we can't see it we got away
- if (escaped)
+ if (QDELETED(target) || !can_see(controller.pawn, target, run_distance))
finish_action(controller, succeeded = TRUE, target_key = target_key, hiding_location_key = hiding_location_key)
return
- if (get_dist(controller.pawn, controller.current_movement_target) > required_distance)
- return
- if(plot_path_away_from(controller, target))
+ if (get_dist(controller.pawn, controller.current_movement_target) >= required_distance)
+ return // Still heading over
+ if (plot_path_away_from(controller, target))
return
finish_action(controller, succeeded = FALSE, target_key = target_key, hiding_location_key = hiding_location_key)
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/targetting.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/targetting.dm
index 9d7587c712b..0b9e31db667 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/targetting.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/targetting.dm
@@ -2,6 +2,8 @@
action_cooldown = 2 SECONDS
/// How far can we see stuff?
var/vision_range = 9
+ /// Blackboard key for aggro range, uses vision range if not specified
+ var/aggro_range_key = BB_AGGRO_RANGE
/// Static typecache list of potentially dangerous objs
var/static/list/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/vehicle/sealed/mecha))
@@ -18,11 +20,13 @@
finish_action(controller, succeeded = FALSE)
return
+ var/aggro_range = controller.blackboard[aggro_range_key] || vision_range
+
controller.clear_blackboard_key(target_key)
- var/list/potential_targets = hearers(vision_range, controller.pawn) - living_mob //Remove self, so we don't suicide
+ var/list/potential_targets = hearers(aggro_range, controller.pawn) - living_mob //Remove self, so we don't suicide
- for(var/HM in typecache_filter_list(range(vision_range, living_mob), hostile_machines)) //Can we see any hostile machines?
- if(can_see(living_mob, HM, vision_range))
+ for(var/HM in typecache_filter_list(range(aggro_range, living_mob), hostile_machines)) //Can we see any hostile machines?
+ if(can_see(living_mob, HM, aggro_range))
potential_targets += HM
if(!potential_targets.len)
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/flee_target.dm b/code/datums/ai/basic_mobs/basic_subtrees/flee_target.dm
index a4982fa660e..8d1391f7c7d 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/flee_target.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/flee_target.dm
@@ -9,8 +9,13 @@
/datum/ai_planning_subtree/flee_target/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
. = ..()
- if (!controller.blackboard[BB_BASIC_MOB_FLEEING] || !controller.blackboard_key_exists(target_key))
+ var/atom/flee_from = controller.blackboard[target_key]
+ if (!controller.blackboard[BB_BASIC_MOB_FLEEING] || QDELETED(flee_from))
return
+ var/flee_distance = controller.blackboard[BB_BASIC_MOB_FLEE_DISTANCE] || DEFAULT_BASIC_FLEE_DISTANCE
+ if (get_dist(controller.pawn, flee_from) >= flee_distance)
+ return
+
controller.queue_behavior(flee_behaviour, target_key, hiding_place_key)
return SUBTREE_RETURN_FINISH_PLANNING //we gotta get out of here.
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/maintain_distance.dm b/code/datums/ai/basic_mobs/basic_subtrees/maintain_distance.dm
index b80a28836a0..c09e7cdbf75 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/maintain_distance.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/maintain_distance.dm
@@ -3,7 +3,7 @@
/// Blackboard key holding atom we want to stay away from
var/target_key = BB_BASIC_MOB_CURRENT_TARGET
/// How close will we allow our target to get?
- var/minimum_distance = 3
+ var/minimum_distance = 4
/// How far away will we allow our target to get?
var/maximum_distance = 6
/// How far do we look for our target?
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm b/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm
index 005a9ee835d..52f4a3459bf 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm
@@ -22,24 +22,31 @@
emote_see = string_list(emote_see)
/datum/ai_planning_subtree/random_speech/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
- if(SPT_PROB(speech_chance, seconds_per_tick))
- var/audible_emotes_length = emote_hear?.len
- var/non_audible_emotes_length = emote_see?.len
- var/speak_lines_length = speak?.len
+ if(!SPT_PROB(speech_chance, seconds_per_tick))
+ return
+ speak(controller)
+
+/// Actually perform an action
+/datum/ai_planning_subtree/random_speech/proc/speak(datum/ai_controller/controller)
+ var/audible_emotes_length = emote_hear?.len
+ var/non_audible_emotes_length = emote_see?.len
+ var/speak_lines_length = speak?.len
- var/total_choices_length = audible_emotes_length + non_audible_emotes_length + speak_lines_length
+ var/total_choices_length = audible_emotes_length + non_audible_emotes_length + speak_lines_length
- var/random_number_in_range = rand(1, total_choices_length)
+ var/random_number_in_range = rand(1, total_choices_length)
+ var/sound_to_play = length(sound) > 0 ? pick(sound) : null
- if(random_number_in_range <= audible_emotes_length)
- controller.queue_behavior(/datum/ai_behavior/perform_emote, pick(emote_hear))
- else if(random_number_in_range <= (audible_emotes_length + non_audible_emotes_length))
- controller.queue_behavior(/datum/ai_behavior/perform_emote, pick(emote_see))
- else
- controller.queue_behavior(/datum/ai_behavior/perform_speech, pick(speak), length(sound) > 0 ? pick(sound) : null)
+ if(random_number_in_range <= audible_emotes_length)
+ controller.queue_behavior(/datum/ai_behavior/perform_emote, pick(emote_hear), sound_to_play)
+ else if(random_number_in_range <= (audible_emotes_length + non_audible_emotes_length))
+ controller.queue_behavior(/datum/ai_behavior/perform_emote, pick(emote_see))
+ else
+ controller.queue_behavior(/datum/ai_behavior/perform_speech, pick(speak), sound_to_play)
/datum/ai_planning_subtree/random_speech/insect
speech_chance = 5
+ sound = list('sound/creatures/chitter.ogg')
emote_hear = list("chitters.")
/datum/ai_planning_subtree/random_speech/mothroach
@@ -49,6 +56,7 @@
/datum/ai_planning_subtree/random_speech/mouse
speech_chance = 1
speak = list("Squeak!", "SQUEAK!", "Squeak?")
+ sound = list('sound/creatures/mousesqueek.ogg')
emote_hear = list("squeaks.")
emote_see = list("runs in a circle.", "shakes.")
@@ -93,12 +101,14 @@
/datum/ai_planning_subtree/random_speech/chicken
speech_chance = 15 // really talkative ladies
speak = list("Cluck!", "BWAAAAARK BWAK BWAK BWAK!", "Bwaak bwak.")
+ sound = list('sound/creatures/clucks.ogg', 'sound/creatures/bagawk.ogg')
emote_hear = list("clucks.", "croons.")
emote_see = list("pecks at the ground.","flaps her wings viciously.")
/datum/ai_planning_subtree/random_speech/chick
speech_chance = 4
speak = list("Cherp.", "Cherp?", "Chirrup.", "Cheep!")
+ sound = list('sound/creatures/chick_peep.ogg')
emote_hear = list("cheeps.")
emote_see = list("pecks at the ground.","flaps her tiny wings.")
@@ -160,33 +170,37 @@
/datum/ai_planning_subtree/random_speech/pony
speech_chance = 3
+ sound = list('sound/creatures/pony/whinny01.ogg', 'sound/creatures/pony/whinny02.ogg', 'sound/creatures/pony/whinny03.ogg')
emote_hear = list("whinnies!")
emote_see = list("horses around.")
/datum/ai_planning_subtree/random_speech/pony/tamed
speech_chance = 3
+ sound = list('sound/creatures/pony/snort.ogg')
+ emote_hear = list("snorts.")
emote_see = list("snorts.")
/datum/ai_planning_subtree/random_speech/killer_tomato
speech_chance = 3
- speak = list("gnashes.", "growls lowly.", "snarls.")
- emote_hear = list("gnashes.")
+ emote_hear = list("gnashes.", "growls lowly.", "snarls.")
emote_see = list("salivates.")
/datum/ai_planning_subtree/random_speech/ant
speech_chance = 1
+ speak = list("BZZZZT!", "CHTCHTCHT!", "Bzzz", "ChtChtCht")
+ sound = list('sound/creatures/chitter.ogg')
emote_hear = list("buzzes.", "clacks.")
emote_see = list("shakes their head.", "twitches their antennae.")
- speak = list("BZZZZT!", "CHTCHTCHT!", "Bzzz", "ChtChtCht")
/datum/ai_planning_subtree/random_speech/fox
speech_chance = 1
+ speak = list("Ack-Ack", "Ack-Ack-Ack-Ackawoooo", "Geckers", "Awoo", "Tchoff")
emote_hear = list("howls.", "barks.", "screams.")
emote_see = list("shakes their head.", "shivers.")
- speak = list("Ack-Ack", "Ack-Ack-Ack-Ackawoooo", "Geckers", "Awoo", "Tchoff")
/datum/ai_planning_subtree/random_speech/crab
speech_chance = 1
+ sound = list('sound/creatures/claw_click.ogg')
emote_hear = list("clicks.")
emote_see = list("clacks.")
@@ -207,11 +221,13 @@
var/list/speech_lines = controller.blackboard[BB_BASIC_MOB_SPEAK_LINES]
if(isnull(speech_lines))
return ..()
-
- speak = speech_lines[BB_EMOTE_SAY] ? speech_lines[BB_EMOTE_SAY] : initial(speak)
- emote_see = speech_lines[BB_EMOTE_SEE] ? speech_lines[BB_EMOTE_SEE] : initial(emote_see)
- emote_hear = speech_lines[BB_EMOTE_HEAR] ? speech_lines[BB_EMOTE_HEAR] : initial(emote_hear)
- sound = speech_lines[BB_EMOTE_SOUND] ? speech_lines[BB_EMOTE_SOUND] : initial(sound)
+
+ // Note to future developers: this behaviour a singleton so this probably doesn't work as you would expect
+ // The whole speech tree really needs to be refactored because this isn't how we use AI data these days
+ speak = speech_lines[BB_EMOTE_SAY] || list()
+ emote_see = speech_lines[BB_EMOTE_SEE] || list()
+ emote_hear = speech_lines[BB_EMOTE_HEAR] || list()
+ sound = speech_lines[BB_EMOTE_SOUND] || list()
speech_chance = speech_lines[BB_EMOTE_CHANCE] ? speech_lines[BB_EMOTE_CHANCE] : initial(speech_chance)
return ..()
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/targeted_mob_ability.dm b/code/datums/ai/basic_mobs/basic_subtrees/targeted_mob_ability.dm
index 8d75f797163..d9ee3ef0918 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/targeted_mob_ability.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/targeted_mob_ability.dm
@@ -23,3 +23,6 @@
controller.queue_behavior(use_ability_behaviour, ability_key, target_key)
if (finish_planning)
return SUBTREE_RETURN_FINISH_PLANNING
+
+/datum/ai_planning_subtree/targeted_mob_ability/continue_planning
+ finish_planning = FALSE
diff --git a/code/datums/ai/basic_mobs/generic_controllers.dm b/code/datums/ai/basic_mobs/generic_controllers.dm
new file mode 100644
index 00000000000..208c1833add
--- /dev/null
+++ b/code/datums/ai/basic_mobs/generic_controllers.dm
@@ -0,0 +1,26 @@
+/// The most basic AI tree which just finds a guy and then runs at them to click them
+/datum/ai_controller/basic_controller/simple_hostile
+ blackboard = list(
+ BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
+ )
+
+ ai_movement = /datum/ai_movement/basic_avoidance
+ idle_behavior = /datum/idle_behavior/idle_random_walk
+ planning_subtrees = list(
+ /datum/ai_planning_subtree/simple_find_target,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
+ )
+
+/// Find a target, walk at target, attack intervening obstacles
+/datum/ai_controller/basic_controller/simple_hostile_obstacles
+ blackboard = list(
+ BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
+ )
+
+ ai_movement = /datum/ai_movement/basic_avoidance
+ idle_behavior = /datum/idle_behavior/idle_random_walk
+ planning_subtrees = list(
+ /datum/ai_planning_subtree/simple_find_target,
+ /datum/ai_planning_subtree/attack_obstacle_in_path,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
+ )
diff --git a/code/datums/ai/basic_mobs/targetting_datums/dont_target_friends.dm b/code/datums/ai/basic_mobs/targetting_datums/dont_target_friends.dm
index 8e6c79fda3f..3556e11900f 100644
--- a/code/datums/ai/basic_mobs/targetting_datums/dont_target_friends.dm
+++ b/code/datums/ai/basic_mobs/targetting_datums/dont_target_friends.dm
@@ -39,3 +39,12 @@
/datum/targetting_datum/not_friends/attack_closed_turfs
attack_closed_turf = TRUE
+
+/// Subtype that allows us to target items while deftly avoiding attacking our allies. Be careful when it comes to targetting items as an AI could get trapped targetting something it can't destroy.
+/datum/targetting_datum/basic/not_friends/allow_items
+
+/datum/targetting_datum/basic/not_friends/allow_items/can_attack(mob/living/living_mob, atom/the_target)
+ . = ..()
+ if(isitem(the_target))
+ // trust fall exercise
+ return TRUE
diff --git a/code/datums/ai/generic/generic_behaviors.dm b/code/datums/ai/generic/generic_behaviors.dm
index e7bfe7a7c60..4f816de4be3 100644
--- a/code/datums/ai/generic/generic_behaviors.dm
+++ b/code/datums/ai/generic/generic_behaviors.dm
@@ -287,11 +287,13 @@
/datum/ai_behavior/perform_emote
-/datum/ai_behavior/perform_emote/perform(seconds_per_tick, datum/ai_controller/controller, emote)
+/datum/ai_behavior/perform_emote/perform(seconds_per_tick, datum/ai_controller/controller, emote, speech_sound)
var/mob/living/living_pawn = controller.pawn
if(!istype(living_pawn))
return
living_pawn.manual_emote(emote)
+ if(speech_sound) // Only audible emotes will pass in a sound
+ playsound(living_pawn, speech_sound, 80, vary = TRUE)
finish_action(controller, TRUE)
/datum/ai_behavior/perform_speech
@@ -305,6 +307,16 @@
playsound(living_pawn, speech_sound, 80, vary = TRUE)
finish_action(controller, TRUE)
+/datum/ai_behavior/perform_speech_radio
+
+/datum/ai_behavior/perform_speech_radio/perform(seconds_per_tick, datum/ai_controller/controller, speech, obj/item/radio/speech_radio, list/try_channels = list(RADIO_CHANNEL_COMMON))
+ var/mob/living/living_pawn = controller.pawn
+ if(!istype(living_pawn) || !istype(speech_radio) || QDELETED(speech_radio) || !length(try_channels))
+ finish_action(controller, FALSE)
+ return
+ speech_radio.talk_into(living_pawn, speech, pick(try_channels))
+ finish_action(controller, TRUE)
+
//song behaviors
/datum/ai_behavior/setup_instrument
diff --git a/code/datums/ai/robot_customer/robot_customer_behaviors.dm b/code/datums/ai/robot_customer/robot_customer_behaviors.dm
index ff9e59c3931..95260b8e68d 100644
--- a/code/datums/ai/robot_customer/robot_customer_behaviors.dm
+++ b/code/datums/ai/robot_customer/robot_customer_behaviors.dm
@@ -3,7 +3,7 @@
/datum/ai_behavior/find_seat/perform(seconds_per_tick, datum/ai_controller/controller)
. = ..()
- var/mob/living/simple_animal/robot_customer/customer_pawn = controller.pawn
+ var/mob/living/basic/robot_customer/customer_pawn = controller.pawn
var/datum/customer_data/customer_data = controller.blackboard[BB_CUSTOMER_CUSTOMERINFO]
var/datum/venue/attending_venue = controller.blackboard[BB_CUSTOMER_ATTENDING_VENUE]
@@ -44,7 +44,7 @@
/datum/ai_behavior/order_food/perform(seconds_per_tick, datum/ai_controller/controller)
. = ..()
- var/mob/living/simple_animal/robot_customer/customer_pawn = controller.pawn
+ var/mob/living/basic/robot_customer/customer_pawn = controller.pawn
var/datum/customer_data/customer_data = controller.blackboard[BB_CUSTOMER_CUSTOMERINFO]
var/obj/structure/holosign/robot_seat/seat_marker = controller.blackboard[BB_CUSTOMER_MY_SEAT]
if(get_turf(seat_marker) == get_turf(customer_pawn))
@@ -75,7 +75,7 @@
// SPT_PROB 1.5 is about a 40% chance that the tourist will have vocalised at least once every minute.
if(SPT_PROB(0.85, seconds_per_tick))
- var/mob/living/simple_animal/robot_customer/customer_pawn = controller.pawn
+ var/mob/living/basic/robot_customer/customer_pawn = controller.pawn
var/datum/customer_data/customer_data = controller.blackboard[BB_CUSTOMER_CUSTOMERINFO]
customer_pawn.say(pick(customer_data.wait_for_food_lines))
@@ -98,7 +98,7 @@
/datum/ai_behavior/wait_for_food/finish_action(datum/ai_controller/controller, succeeded)
. = ..()
- var/mob/living/simple_animal/robot_customer/customer_pawn = controller.pawn
+ var/mob/living/basic/robot_customer/customer_pawn = controller.pawn
var/datum/customer_data/customer_data = controller.blackboard[BB_CUSTOMER_CUSTOMERINFO]
var/mob/living/greytider = controller.blackboard[BB_CUSTOMER_CURRENT_TARGET]
//usually if we stop waiting, it's because we're done with the venue. but here we're either beating some dude up
diff --git a/code/datums/ai/robot_customer/robot_customer_controller.dm b/code/datums/ai/robot_customer/robot_customer_controller.dm
index 2a633590f68..0fc9d27eb43 100644
--- a/code/datums/ai/robot_customer/robot_customer_controller.dm
+++ b/code/datums/ai/robot_customer/robot_customer_controller.dm
@@ -1,14 +1,16 @@
/datum/ai_controller/robot_customer
ai_movement = /datum/ai_movement/basic_avoidance
movement_delay = 0.8 SECONDS
- blackboard = list(BB_CUSTOMER_CURRENT_ORDER = null,
- BB_CUSTOMER_MY_SEAT = null,
- BB_CUSTOMER_PATIENCE = 999,
- BB_CUSTOMER_CUSTOMERINFO = null,
- BB_CUSTOMER_EATING = FALSE,
- BB_CUSTOMER_LEAVING = FALSE,
- BB_CUSTOMER_ATTENDING_VENUE = null,
- BB_CUSTOMER_SAID_CANT_FIND_SEAT_LINE = FALSE)
+ blackboard = list(
+ BB_CUSTOMER_ATTENDING_VENUE = null,
+ BB_CUSTOMER_CURRENT_ORDER = null,
+ BB_CUSTOMER_CUSTOMERINFO = null,
+ BB_CUSTOMER_EATING = FALSE,
+ BB_CUSTOMER_LEAVING = FALSE,
+ BB_CUSTOMER_MY_SEAT = null,
+ BB_CUSTOMER_PATIENCE = 999 SECONDS,
+ BB_CUSTOMER_SAID_CANT_FIND_SEAT_LINE = FALSE,
+ )
planning_subtrees = list(/datum/ai_planning_subtree/robot_customer)
/datum/ai_controller/robot_customer/Destroy()
@@ -18,7 +20,7 @@
return ..()
/datum/ai_controller/robot_customer/TryPossessPawn(atom/new_pawn)
- if(!istype(new_pawn, /mob/living/simple_animal/robot_customer))
+ if(!istype(new_pawn, /mob/living/basic/robot_customer))
return AI_CONTROLLER_INCOMPATIBLE
new_pawn.AddElement(/datum/element/relay_attackers)
RegisterSignal(new_pawn, COMSIG_ATOM_ATTACKBY, PROC_REF(on_attackby))
@@ -28,6 +30,12 @@
return ..() //Run parent at end
/datum/ai_controller/robot_customer/UnpossessPawn(destroy)
+ if(isnull(pawn))
+#ifndef UNIT_TESTS
+ stack_trace("Robot Customer AI Controller UnpossessPawn called with null pawn! This shouldn't happen in normal circumstances.") // and unit tests are abnormal circumstances
+#endif
+ return
+
UnregisterSignal(pawn, list(COMSIG_ATOM_ATTACKBY, COMSIG_ATOM_WAS_ATTACKED, COMSIG_LIVING_GET_PULLED, COMSIG_ATOM_ATTACK_HAND))
return ..() //Run parent at end
@@ -67,7 +75,7 @@
INVOKE_ASYNC(src, PROC_REF(async_on_get_pulled), source, puller)
/datum/ai_controller/robot_customer/proc/async_on_get_pulled(datum/source, mob/living/puller)
- var/mob/living/simple_animal/robot_customer/customer = pawn
+ var/mob/living/basic/robot_customer/customer = pawn
var/datum/customer_data/customer_data = blackboard[BB_CUSTOMER_CUSTOMERINFO]
var/datum/venue/attending_venue = blackboard[BB_CUSTOMER_ATTENDING_VENUE]
@@ -81,12 +89,12 @@
/datum/ai_controller/robot_customer/proc/dont_want_that(mob/living/chef, obj/item/thing)
- var/mob/living/simple_animal/robot_customer/customer = pawn
+ var/mob/living/basic/robot_customer/customer = pawn
var/datum/customer_data/customer_data = blackboard[BB_CUSTOMER_CUSTOMERINFO]
customer.say(customer_data.wrong_item_line)
/datum/ai_controller/robot_customer/proc/warn_greytider(mob/living/greytider)
- var/mob/living/simple_animal/robot_customer/customer = pawn
+ var/mob/living/basic/robot_customer/customer = pawn
var/datum/venue/attending_venue = blackboard[BB_CUSTOMER_ATTENDING_VENUE]
var/datum/customer_data/customer_data = blackboard[BB_CUSTOMER_CUSTOMERINFO]
//Living mobs are tagged, so these will always be valid
diff --git a/code/datums/atmosphere/_atmosphere.dm b/code/datums/atmosphere/_atmosphere.dm
index 1dace1dd1b2..702a42e7ab0 100644
--- a/code/datums/atmosphere/_atmosphere.dm
+++ b/code/datums/atmosphere/_atmosphere.dm
@@ -52,6 +52,9 @@
ASSERT_GAS_IN_LIST(gastype, gaslist)
gaslist[gastype][MOLES] += amount
+ // Ensure that minimum_pressure is actually a hard lower limit
+ target_pressure = clamp(target_pressure, minimum_pressure + (gaslist[gastype][MOLES] * 0.1), maximum_pressure)
+
// That last one put us over the limit, remove some of it
while(gasmix.return_pressure() > target_pressure)
gaslist[gastype][MOLES] -= gaslist[gastype][MOLES] * 0.1
diff --git a/code/datums/components/acid.dm b/code/datums/components/acid.dm
index 9758cd0c1b6..1d9cf9e87d6 100644
--- a/code/datums/components/acid.dm
+++ b/code/datums/components/acid.dm
@@ -78,8 +78,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
QDEL_NULL(sizzle)
if(particle_effect)
QDEL_NULL(particle_effect)
- if(process_effect)
- process_effect = null
+ process_effect = null
return ..()
/datum/component/acid/RegisterWithParent()
diff --git a/code/datums/components/appearance_on_aggro.dm b/code/datums/components/appearance_on_aggro.dm
index affb926d28d..33a3d7c2e90 100644
--- a/code/datums/components/appearance_on_aggro.dm
+++ b/code/datums/components/appearance_on_aggro.dm
@@ -1,11 +1,14 @@
/**
- * component gave to basic creatures to allow them to change appearance when find a target
+ * Changes visuals of the attached mob while it has a target
*/
/datum/component/appearance_on_aggro
+ /// Blackboardey to search for a target
var/target_key = BB_BASIC_MOB_CURRENT_TARGET
+ /// Icon state to use when we have a target
+ var/aggro_state
/// path of the overlay to apply
- var/mutable_appearance/overlay_path
+ var/mutable_appearance/aggro_overlay
/// visibility of our icon when aggroed
var/alpha_on_aggro
/// visibility of our icon when deaggroed
@@ -13,20 +16,22 @@
/// do we currently have a target
var/atom/current_target
-/datum/component/appearance_on_aggro/Initialize(overlay_icon, overlay_state, alpha_on_aggro, alpha_on_deaggro)
- if(!isliving(parent))
+/datum/component/appearance_on_aggro/Initialize(aggro_state, overlay_icon, overlay_state, alpha_on_aggro, alpha_on_deaggro)
+ if (!isliving(parent))
return COMPONENT_INCOMPATIBLE
- if(overlay_icon && overlay_state)
- src.overlay_path = mutable_appearance(overlay_icon, overlay_state)
- if(!alpha_on_aggro || !alpha_on_deaggro)
- return
+ src.aggro_state = aggro_state
src.alpha_on_aggro = alpha_on_aggro
src.alpha_on_deaggro = alpha_on_deaggro
+ if (!isnull(overlay_icon) && !isnull(overlay_state))
+ aggro_overlay = mutable_appearance(overlay_icon, overlay_state)
/datum/component/appearance_on_aggro/RegisterWithParent()
- RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(change_overlays))
RegisterSignal(parent, COMSIG_AI_BLACKBOARD_KEY_SET(target_key), PROC_REF(on_set_target))
RegisterSignal(parent, COMSIG_AI_BLACKBOARD_KEY_CLEARED(target_key), PROC_REF(on_clear_target))
+ if (!isnull(aggro_state))
+ RegisterSignal(parent, COMSIG_ATOM_UPDATE_ICON_STATE, PROC_REF(on_icon_state_updated))
+ if (!isnull(aggro_overlay))
+ RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_overlays_updated))
/datum/component/appearance_on_aggro/UnregisterFromParent()
. = ..()
@@ -36,37 +41,42 @@
SIGNAL_HANDLER
var/atom/target = source.ai_controller.blackboard[target_key]
- if(isnull(target))
+ if (QDELETED(target))
return
+
current_target = target
RegisterSignal(target, COMSIG_QDELETING, PROC_REF(on_clear_target))
- if(overlay_path)
- source.update_appearance(UPDATE_OVERLAYS)
- if(alpha_on_aggro)
+ if (!isnull(aggro_overlay) || !isnull(aggro_state))
+ source.update_appearance(UPDATE_ICON)
+ if (!isnull(alpha_on_aggro))
animate(source, alpha = alpha_on_aggro, time = 2 SECONDS)
/datum/component/appearance_on_aggro/Destroy()
- if(current_target)
+ if (!isnull(current_target))
revert_appearance(parent)
return ..()
/datum/component/appearance_on_aggro/proc/on_clear_target(atom/source)
SIGNAL_HANDLER
-
revert_appearance(parent)
/datum/component/appearance_on_aggro/proc/revert_appearance(mob/living/source)
UnregisterSignal(current_target, COMSIG_QDELETING)
current_target = null
- if(overlay_path)
- source.update_appearance(UPDATE_OVERLAYS)
- if(alpha_on_deaggro)
+ if (!isnull(aggro_overlay) || !isnull(aggro_state))
+ source.update_appearance(UPDATE_ICON)
+ if (!isnull(alpha_on_deaggro))
animate(source, alpha = alpha_on_deaggro, time = 2 SECONDS)
-/datum/component/appearance_on_aggro/proc/change_overlays(atom/source, list/overlays)
+/datum/component/appearance_on_aggro/proc/on_icon_state_updated(mob/living/source)
SIGNAL_HANDLER
-
- if(isnull(current_target))
+ if (source.stat == DEAD)
return
+ source.icon_state = isnull(current_target) ? initial(source.icon_state) : aggro_state
- overlays += overlay_path
+/datum/component/appearance_on_aggro/proc/on_overlays_updated(atom/source, list/overlays)
+ SIGNAL_HANDLER
+
+ if (isnull(current_target))
+ return
+ overlays += aggro_overlay
diff --git a/code/datums/components/crafting/_recipes.dm b/code/datums/components/crafting/_recipes.dm
index 246f04df0f5..4254804974e 100644
--- a/code/datums/components/crafting/_recipes.dm
+++ b/code/datums/components/crafting/_recipes.dm
@@ -17,7 +17,7 @@
var/list/tool_paths
///time in seconds. Remember to use the SECONDS define!
var/time = 3 SECONDS
- ///type paths of items that will be placed in the result
+ ///type paths of items that will be forceMoved() into the result, or added to the reagents of it
var/list/parts = list()
///like tool_behaviors but for reagents
var/list/chem_catalysts = list()
diff --git a/code/datums/components/crafting/guncrafting.dm b/code/datums/components/crafting/guncrafting.dm
index f239288b031..a5a20d4326b 100644
--- a/code/datums/components/crafting/guncrafting.dm
+++ b/code/datums/components/crafting/guncrafting.dm
@@ -2,12 +2,27 @@
// PARTS //
+/obj/item/weaponcrafting/Initialize(mapload)
+ . = ..()
+ create_slapcraft_component()
+
+/obj/item/weaponcrafting/proc/create_slapcraft_component()
+ return
+
/obj/item/weaponcrafting/receiver
name = "modular receiver"
desc = "A prototype modular receiver and trigger assembly for a firearm."
icon = 'icons/obj/weapons/improvised.dmi'
icon_state = "receiver"
+/obj/item/weaponcrafting/receiver/create_slapcraft_component()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/pipegun)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/weaponcrafting/stock
name = "rifle stock"
desc = "A classic rifle stock that doubles as a grip, roughly carved out of wood."
@@ -16,17 +31,33 @@
icon = 'icons/obj/weapons/improvised.dmi'
icon_state = "riflestock"
+/obj/item/weaponcrafting/stock/create_slapcraft_component()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/smoothbore_disabler, /datum/crafting_recipe/laser_musket)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/weaponcrafting/giant_wrench
name = "Big Slappy parts kit"
desc = "Illegal parts to make a giant like wrench commonly known as a Big Slappy."
icon = 'icons/obj/weapons/improvised.dmi'
icon_state = "weaponkit_gw"
+/obj/item/weaponcrafting/giant_wrench/create_slapcraft_component() // slappycraft
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/giant_wrench)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
///These gun kits are printed from the security protolathe to then be used in making new weapons
// GUN PART KIT //
-/obj/item/weaponcrafting/gunkit
+/obj/item/weaponcrafting/gunkit // These don't get a slapcraft component, it's added to the gun - more intuitive player-facing to slap the kit onto the gun.
name = "generic gun parts kit"
desc = "It's an empty gun parts container! Why do you have this?"
icon = 'icons/obj/weapons/improvised.dmi'
diff --git a/code/datums/components/crafting/slapcrafting.dm b/code/datums/components/crafting/slapcrafting.dm
new file mode 100644
index 00000000000..32a901dc73e
--- /dev/null
+++ b/code/datums/components/crafting/slapcrafting.dm
@@ -0,0 +1,202 @@
+/// Slapcrafting component!
+/datum/component/slapcrafting
+ dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
+ var/list/slapcraft_recipes = list()
+
+/**
+ * Slapcraft component
+ *
+ * Slap it onto a item to be able to slapcraft with it
+ *
+ * args:
+ * * slapcraft_recipes (required) = The recipe to attempt crafting.
+ * Hit it with an ingredient of the recipe to attempt crafting.
+ * It will check the area near the user for the rest of the ingredients and tools.
+ * *
+**/
+/datum/component/slapcrafting/Initialize(
+ slapcraft_recipes = null,
+ )
+
+ if(!isitem(parent))
+ return COMPONENT_INCOMPATIBLE
+
+ var/obj/item/parent_item = parent
+
+ if((parent_item.item_flags & ABSTRACT) || (parent_item.item_flags & DROPDEL))
+ return COMPONENT_NOTRANSFER
+
+ RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, PROC_REF(attempt_slapcraft))
+ RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(get_examine_info))
+ RegisterSignal(parent, COMSIG_ATOM_EXAMINE_MORE, PROC_REF(get_examine_more_info))
+ RegisterSignal(parent, COMSIG_TOPIC, PROC_REF(topic_handler))
+
+ src.slapcraft_recipes += slapcraft_recipes
+
+/datum/component/slapcrafting/InheritComponent(datum/component/slapcrafting/new_comp, original, slapcraft_recipes)
+ if(!original)
+ return
+ src.slapcraft_recipes += slapcraft_recipes
+
+/datum/component/slapcrafting/Destroy(force, silent)
+ UnregisterSignal(parent, list(COMSIG_ATOM_ATTACKBY, COMSIG_ATOM_EXAMINE, COMSIG_ATOM_EXAMINE_MORE))
+ return ..()
+
+/datum/component/slapcrafting/proc/attempt_slapcraft(obj/item/parent_item, obj/item/slapper, mob/user)
+
+ if(isnull(slapcraft_recipes))
+ CRASH("NULL SLAPCRAFT RECIPES?")
+
+ var/datum/component/personal_crafting/craft_sheet = user.GetComponent(/datum/component/personal_crafting)
+ if(!craft_sheet)
+ CRASH("No craft sheet on user ??")
+
+ var/list/valid_recipes
+ for(var/datum/crafting_recipe/recipe as anything in slapcraft_recipes)
+ // Gotta instance it to copy the list over.
+ recipe = new recipe()
+ var/list/type_ingredient_list = recipe.reqs
+ qdel(recipe)
+ if(length(type_ingredient_list) == 1) // No ingredients besides itself? We use one of the tools then
+ type_ingredient_list = recipe.tool_paths
+ // Check the tool behaviours differently as they aren't types
+ for(var/behaviour in initial(recipe.tool_behaviors))
+ if(slapper.tool_behaviour == behaviour)
+ LAZYADD(valid_recipes, recipe)
+ break
+ if(is_type_in_list(slapper, type_ingredient_list))
+ LAZYADD(valid_recipes, recipe)
+
+ if(!valid_recipes)
+ return
+
+ // We might use radials so we need to split the proc chain
+ INVOKE_ASYNC(src, PROC_REF(slapcraft_async), valid_recipes, user, craft_sheet)
+
+/datum/component/slapcrafting/proc/slapcraft_async(list/valid_recipes, mob/user, datum/component/personal_crafting/craft_sheet)
+
+ var/list/recipe_choices = list()
+
+ var/list/result_to_recipe = list()
+
+ var/final_recipe = valid_recipes[1]
+ var/string_chosen_recipe
+ if(length(valid_recipes) > 1)
+ for(var/datum/crafting_recipe/recipe as anything in valid_recipes)
+ var/atom/recipe_result = initial(recipe.result)
+ result_to_recipe[initial(recipe_result.name)] = recipe
+ recipe_choices += list("[initial(recipe_result.name)]" = image(icon = initial(recipe_result.icon), icon_state = initial(recipe_result.icon_state)))
+
+ if(!recipe_choices)
+ CRASH("No recipe choices despite validating in earlier proc")
+
+ string_chosen_recipe = show_radial_menu(user, parent, recipe_choices, require_near = TRUE)
+ if(isnull(string_chosen_recipe))
+ return // they closed the thing
+
+ if(string_chosen_recipe)
+ final_recipe = result_to_recipe[string_chosen_recipe]
+
+
+ var/datum/crafting_recipe/actual_recipe = final_recipe
+
+ if(istype(actual_recipe, /datum/crafting_recipe/food))
+ actual_recipe = locate(final_recipe) in GLOB.cooking_recipes
+ else
+ actual_recipe = locate(final_recipe) in GLOB.crafting_recipes
+
+ if(!actual_recipe)
+ CRASH("Recipe not located in cooking or crafting recipes: [final_recipe]")
+
+ var/atom/final_result = initial(actual_recipe.result)
+
+ to_chat(user, span_notice("You start crafting \a [initial(final_result.name)]..."))
+
+ var/error_string = craft_sheet.construct_item(user, actual_recipe)
+
+ if(!isatom(error_string))
+ to_chat(user, span_warning("crafting failed" + error_string))
+
+/// Alerts any examiners to the recipe, if they wish to know more.
+/datum/component/slapcrafting/proc/get_examine_info(atom/source, mob/user, list/examine_list)
+ SIGNAL_HANDLER
+
+ var/list/string_results = list()
+ // This list saves the recipe result names we've already used to cross-check other recipes so we don't have ', a spear, or a spear!' in the desc.
+ var/list/already_used_names
+ for(var/datum/crafting_recipe/recipe as anything in slapcraft_recipes)
+ // Identical name to a previous recipe's result? Skip in description.
+ var/atom/result = initial(recipe.result)
+ if(locate(initial(result.name)) in already_used_names)
+ continue
+ already_used_names += initial(result.name)
+ string_results += list("\a [initial(result.name)]")
+
+ examine_list += span_notice("You think [parent] could be used to make [english_list(string_results)]! Examine again to look at the details...")
+
+/// Alerts any examiners to the details of the recipe.
+/datum/component/slapcrafting/proc/get_examine_more_info(atom/source, mob/user, list/examine_list)
+ SIGNAL_HANDLER
+
+ for(var/datum/crafting_recipe/recipe as anything in slapcraft_recipes)
+ var/atom/result = initial(recipe.result)
+ examine_list += "See Recipe For [initial(result.name)]"
+
+/datum/component/slapcrafting/proc/topic_handler(atom/source, user, href_list)
+ SIGNAL_HANDLER
+
+ if(!href_list["check_recipe"])
+ return
+
+ var/datum/crafting_recipe/cur_recipe = locate(href_list["check_recipe"]) in slapcraft_recipes
+
+ if(isnull(cur_recipe))
+ CRASH("null recipe!")
+
+ var/atom/result = initial(cur_recipe.result)
+
+ to_chat(user, span_notice("You could craft \a [initial(result.name)] by applying one of these items to it!"))
+
+ // Gotta instance it to copy the lists over.
+ cur_recipe = new cur_recipe()
+ var/list/type_ingredient_list = cur_recipe.reqs
+
+ // Final return string.
+ var/string_ingredient_list = ""
+
+ // Check the ingredients of the crafting recipe.
+ for(var/valid_type in type_ingredient_list)
+ // Check if they're datums, specifically reagents.
+ var/datum/reagent/reagent_ingredient = valid_type
+ if(istype(reagent_ingredient))
+ var/amount = initial(cur_recipe.reqs[reagent_ingredient])
+ string_ingredient_list += "[amount] unit[amount > 1 ? "s" : ""] of [initial(reagent_ingredient.name)]\n"
+
+ // Redundant!
+ if(parent.type == valid_type)
+ continue
+ var/atom/ingredient = valid_type
+ var/amount = initial(cur_recipe.reqs[ingredient])
+ string_ingredient_list += "[amount > 1 ? ("[amount]" + " of") : "a"] [initial(ingredient.name)]\n"
+
+ // If we did find ingredients then add them onto the list.
+ if(length(string_ingredient_list))
+ to_chat(user, span_boldnotice("Ingredients:"))
+ to_chat(user, examine_block(span_notice(string_ingredient_list)))
+
+ var/list/tool_list = ""
+
+ // Paste the required tools.
+ for(var/valid_type in cur_recipe.tool_paths)
+ var/atom/tool = valid_type
+ tool_list += "\a [initial(tool.name)]\n"
+
+ for(var/string in cur_recipe.tool_behaviors)
+ tool_list += "\a [string]\n"
+
+ if(length(tool_list))
+ to_chat(user, span_boldnotice("Required Tools:"))
+ to_chat(user, examine_block(span_notice(tool_list)))
+
+ qdel(cur_recipe)
+
diff --git a/code/datums/components/death_linked.dm b/code/datums/components/death_linked.dm
new file mode 100644
index 00000000000..59d2ce5e855
--- /dev/null
+++ b/code/datums/components/death_linked.dm
@@ -0,0 +1,30 @@
+/**
+ * ## Death link component
+ *
+ * When the owner of this component dies it also gibs a linked mob
+ */
+/datum/component/death_linked
+ ///The mob that also dies when the user dies
+ var/datum/weakref/linked_mob
+
+/datum/component/death_linked/Initialize(mob/living/target_mob)
+ . = ..()
+ if(!isliving(parent))
+ return COMPONENT_INCOMPATIBLE
+ if(isnull(target_mob))
+ stack_trace("[type] added to [parent] with no linked mob.")
+ src.linked_mob = WEAKREF(target_mob)
+
+/datum/component/death_linked/RegisterWithParent()
+ . = ..()
+ RegisterSignal(parent, COMSIG_LIVING_DEATH, PROC_REF(on_death))
+
+/datum/component/death_linked/UnregisterFromParent()
+ . = ..()
+ UnregisterSignal(parent, COMSIG_LIVING_DEATH)
+
+///signal called by the stat of the target changing
+/datum/component/death_linked/proc/on_death(mob/living/target, gibbed)
+ SIGNAL_HANDLER
+ var/mob/living/linked_mob_resolved = linked_mob?.resolve()
+ linked_mob_resolved?.gib()
diff --git a/code/datums/components/food/ice_cream_holder.dm b/code/datums/components/food/ice_cream_holder.dm
index 9e25c7cb4b4..3e212c52b9a 100644
--- a/code/datums/components/food/ice_cream_holder.dm
+++ b/code/datums/components/food/ice_cream_holder.dm
@@ -33,14 +33,16 @@
var/datum/reagent/sweetener
-/datum/component/ice_cream_holder/Initialize(max_scoops = DEFAULT_MAX_ICE_CREAM_SCOOPS,
- change_name = TRUE,
- filled_name,
- change_desc = FALSE,
- x_offset = 0,
- y_offset = 0,
- datum/reagent/sweetener = /datum/reagent/consumable/sugar,
- list/prefill_flavours)
+/datum/component/ice_cream_holder/Initialize(
+ max_scoops = DEFAULT_MAX_ICE_CREAM_SCOOPS,
+ change_name = TRUE,
+ filled_name,
+ change_desc = FALSE,
+ x_offset = 0,
+ y_offset = 0,
+ datum/reagent/sweetener = /datum/reagent/consumable/sugar,
+ list/prefill_flavours,
+)
if(!IS_EDIBLE(parent)) /// There is no easy way to add servings to those non-item edibles, but I won't stop you.
return COMPONENT_INCOMPATIBLE
@@ -169,7 +171,7 @@
if(compare_list(our_scoops, icecream_order.wanted_flavors))
return COMPONENT_CORRECT_ORDER
-/datum/component/ice_cream_holder/proc/sell_ice_cream(obj/item/source, mob/living/simple_animal/robot_customer/sold_to)
+/datum/component/ice_cream_holder/proc/sell_ice_cream(obj/item/source, mob/living/basic/robot_customer/sold_to)
SIGNAL_HANDLER
//the price of ice cream scales with the number of scoops. Yummy.
diff --git a/code/datums/components/religious_tool.dm b/code/datums/components/religious_tool.dm
index e64e28f83a3..4c0646b3a55 100644
--- a/code/datums/components/religious_tool.dm
+++ b/code/datums/components/religious_tool.dm
@@ -74,9 +74,9 @@
/**********Sacrificing**********/
else if(operation_flags & RELIGION_TOOL_SACRIFICE)
- if(easy_access_sect?.can_sacrifice(the_item,user))
+ if(!easy_access_sect?.can_sacrifice(the_item, user))
return
- easy_access_sect.on_sacrifice(the_item,user)
+ easy_access_sect.on_sacrifice(the_item, user)
return COMPONENT_NO_AFTERATTACK
/datum/component/religious_tool/ui_interact(mob/user, datum/tgui/ui)
diff --git a/code/datums/components/supermatter_crystal.dm b/code/datums/components/supermatter_crystal.dm
index a9bdfc5b154..66087134388 100644
--- a/code/datums/components/supermatter_crystal.dm
+++ b/code/datums/components/supermatter_crystal.dm
@@ -17,6 +17,7 @@
RegisterSignal(parent, COMSIG_ATOM_TOOL_ACT(TOOL_WRENCH), PROC_REF(tool_hit))
RegisterSignal(parent, COMSIG_ATOM_BUMPED, PROC_REF(bumped_hit))
RegisterSignal(parent, COMSIG_ATOM_INTERCEPT_Z_FALL, PROC_REF(intercept_z_fall))
+ RegisterSignal(parent, COMSIG_ATOM_ON_Z_IMPACT, PROC_REF(on_z_impact))
src.tool_act_callback = tool_act_callback
src.consume_callback = consume_callback
@@ -38,6 +39,7 @@
COMSIG_ATOM_TOOL_ACT(TOOL_WRENCH),
COMSIG_ATOM_BUMPED,
COMSIG_ATOM_INTERCEPT_Z_FALL,
+ COMSIG_ATOM_ON_Z_IMPACT,
)
UnregisterSignal(parent, signals_to_remove)
@@ -152,6 +154,8 @@
return
if(istype(item, /obj/item/melee/roastingstick))
return FALSE
+ if(istype(item, /obj/item/toy/crayon/spraycan))
+ return FALSE
if(istype(item, /obj/item/clothing/mask/cigarette))
var/obj/item/clothing/mask/cigarette/cig = item
var/clumsy = HAS_TRAIT(user, TRAIT_CLUMSY)
@@ -232,11 +236,36 @@
/datum/component/supermatter_crystal/proc/intercept_z_fall(datum/source, list/falling_movables, levels)
SIGNAL_HANDLER
for(var/atom/movable/hit_object as anything in falling_movables)
- if(hit_object == source)
- continue
+ if(parent == hit_object)
+ return
+
bumped_hit(parent, hit_object)
return FALL_INTERCEPTED | FALL_NO_MESSAGE
+/datum/component/supermatter_crystal/proc/on_z_impact(datum/source, turf/impacted_turf, levels)
+ SIGNAL_HANDLER
+
+ var/atom/atom_source = source
+
+ for(var/mob/living/poor_target in impacted_turf)
+ consume(atom_source, poor_target)
+ playsound(get_turf(atom_source), 'sound/effects/supermatter.ogg', 50, TRUE)
+ poor_target.visible_message(span_danger("\The [atom_source] slams into \the [poor_target] out of nowhere inducing a resonance... [poor_target.p_their()] body starts to glow and burst into flames before flashing into dust!"),
+ span_userdanger("\The [atom_source] slams into you out of nowhere as your ears are filled with unearthly ringing. Your last thought is \"The fuck.\""),
+ span_hear("You hear an unearthly noise as a wave of heat washes over you."))
+
+ for(var/atom/movable/hit_object as anything in impacted_turf)
+ if(parent == hit_object)
+ return
+
+ if(iseffect(hit_object))
+ continue
+
+ consume(atom_source, hit_object)
+ playsound(get_turf(atom_source), 'sound/effects/supermatter.ogg', 50, TRUE)
+ atom_source.visible_message(span_danger("\The [atom_source], smacks into the plating out of nowhere, reducing everything below to ash."), null,
+ span_hear("You hear a loud crack as you are washed with a wave of heat."))
+
/datum/component/supermatter_crystal/proc/dust_mob(datum/source, mob/living/nom, vis_msg, mob_msg, cause)
if(nom.incorporeal_move || nom.status_flags & GODMODE) //try to keep supermatter sliver's + hemostat's dust conditions in sync with this too
return
diff --git a/code/datums/components/tackle.dm b/code/datums/components/tackle.dm
index ffd20cc2c13..4ae3a973d7e 100644
--- a/code/datums/components/tackle.dm
+++ b/code/datums/components/tackle.dm
@@ -205,7 +205,8 @@
user.visible_message(span_warning("[user] lands an expert [tackle_word] on [target], knocking [target.p_them()] down hard while landing on [user.p_their()] feet with a passive grip!"), span_userdanger("You land an expert [tackle_word] on [target], knocking [target.p_them()] down hard while landing on your feet with a passive grip!"), ignored_mobs = target)
to_chat(target, span_userdanger("[user] lands an expert [tackle_word] on you, knocking you down hard and maintaining a passive grab!"))
- user.SetKnockdown(0)
+ // Ignore_canstun has to be true, or else a stunimmune user would stay knocked down.
+ user.SetKnockdown(0, ignore_canstun = TRUE)
user.get_up(TRUE)
user.forceMove(get_turf(target))
target.adjustStaminaLoss(40)
@@ -228,7 +229,8 @@
user.visible_message(span_warning("[user] lands a monster [tackle_word] on [target], knocking [target.p_them()] senseless and applying an aggressive pin!"), span_userdanger("You land a monster [tackle_word] on [target], knocking [target.p_them()] senseless and applying an aggressive pin!"), ignored_mobs = target)
to_chat(target, span_userdanger("[user] lands a monster [tackle_word] on you, knocking you senseless and aggressively pinning you!"))
- user.SetKnockdown(0)
+ // Ignore_canstun has to be true, or else a stunimmune user would stay knocked down.
+ user.SetKnockdown(0, ignore_canstun = TRUE)
user.get_up(TRUE)
user.forceMove(get_turf(target))
target.adjustStaminaLoss(40)
diff --git a/code/datums/components/wall_mounted.dm b/code/datums/components/wall_mounted.dm
index 6164d39b001..8d1722f89fe 100644
--- a/code/datums/components/wall_mounted.dm
+++ b/code/datums/components/wall_mounted.dm
@@ -17,7 +17,7 @@
/datum/component/wall_mounted/RegisterWithParent()
RegisterSignal(hanging_wall_turf, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
- RegisterSignal(hanging_wall_turf, COMSIG_TURF_CHANGE, PROC_REF(drop_wallmount))
+ RegisterSignal(hanging_wall_turf, COMSIG_TURF_CHANGE, PROC_REF(on_turf_changing))
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(drop_wallmount))
RegisterSignal(parent, COMSIG_QDELETING, PROC_REF(on_linked_destroyed))
@@ -41,6 +41,14 @@
SIGNAL_HANDLER
examine_list += span_notice("\The [hanging_wall_turf] is currently supporting [span_bold("[parent]")]. Deconstruction or excessive damage would cause it to [span_bold("fall to the ground")].")
+/**
+ * When the type of turf changes, if it is changing into a floor we should drop our contents
+ */
+/datum/component/wall_mounted/proc/on_turf_changing(datum/source, path, new_baseturfs, flags, post_change_callbacks)
+ SIGNAL_HANDLER
+ if (ispath(path, /turf/open))
+ drop_wallmount()
+
/**
* Handles the dropping of the linked object. This is done via deconstruction, as that should be the most sane way to handle it for most objects.
* Except for intercoms, which are handled by creating a new wallframe intercom, as they're apparently items.
diff --git a/code/datums/elements/death_linked.dm b/code/datums/elements/death_linked.dm
deleted file mode 100644
index c5d2c6c422c..00000000000
--- a/code/datums/elements/death_linked.dm
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * ## death linkage element!
- *
- * Bespoke element that when the owner dies, the linked mob dies too.
- */
-/datum/element/death_linked
- element_flags = ELEMENT_BESPOKE
- argument_hash_start_idx = 3
- ///The mob that also dies when the user dies
- var/datum/weakref/linked_mob
-
-/datum/element/death_linked/Attach(datum/target, mob/living/target_mob)
- . = ..()
- if(!isliving(target))
- return ELEMENT_INCOMPATIBLE
- if(!target_mob)
- stack_trace("[type] added to [target] with NO MOB.")
- src.linked_mob = WEAKREF(target_mob)
- RegisterSignal(target, COMSIG_LIVING_DEATH, PROC_REF(on_death))
-
-/datum/element/death_linked/Detach(datum/target)
- . = ..()
- UnregisterSignal(target, COMSIG_LIVING_DEATH)
-
-///signal called by the stat of the target changing
-/datum/element/death_linked/proc/on_death(mob/living/target, gibbed)
- SIGNAL_HANDLER
- var/mob/living/linked_mob_resolved = linked_mob?.resolve()
- linked_mob_resolved?.death(TRUE)
diff --git a/code/datums/elements/food/venue_price.dm b/code/datums/elements/food/venue_price.dm
index 1fcf9de040d..be846d7c004 100644
--- a/code/datums/elements/food/venue_price.dm
+++ b/code/datums/elements/food/venue_price.dm
@@ -21,19 +21,19 @@
UnregisterSignal(target, COMSIG_ITEM_SOLD_TO_CUSTOMER)
UnregisterSignal(target, COMSIG_REAGENT_SOLD_TO_CUSTOMER)
-/datum/element/venue_price/proc/item_sold(obj/item/thing_sold, mob/living/simple_animal/robot_customer/sold_to)
+/datum/element/venue_price/proc/item_sold(obj/item/thing_sold, mob/living/basic/robot_customer/sold_to)
SIGNAL_HANDLER
produce_cash(sold_to, thing_sold)
return TRANSACTION_SUCCESS
-/datum/element/venue_price/proc/reagent_sold(datum/reagent/reagent_sold, mob/living/simple_animal/robot_customer/sold_to, obj/item/container)
+/datum/element/venue_price/proc/reagent_sold(datum/reagent/reagent_sold, mob/living/basic/robot_customer/sold_to, obj/item/container)
SIGNAL_HANDLER
produce_cash(sold_to, container)
return TRANSACTION_SUCCESS
-/datum/element/venue_price/proc/produce_cash(mob/living/simple_animal/robot_customer/sold_to, obj/item/container)
+/datum/element/venue_price/proc/produce_cash(mob/living/basic/robot_customer/sold_to, obj/item/container)
new /obj/item/holochip(get_turf(container), venue_price)
playsound(container, 'sound/effects/cashregister.ogg', 60, TRUE)
diff --git a/code/datums/elements/sideway_movement.dm b/code/datums/elements/sideway_movement.dm
index dfe23187807..e6d94745e6c 100644
--- a/code/datums/elements/sideway_movement.dm
+++ b/code/datums/elements/sideway_movement.dm
@@ -23,5 +23,5 @@
return
var/new_dir = old_dir
if(direction == old_dir || direction == REVERSE_DIR(old_dir))
- new_dir = angle2dir(dir2angle(direction) + pick(90, -90))
+ new_dir = turn(source.dir, pick(90, -90))
source.setDir(new_dir)
diff --git a/code/datums/mapgen/CaveGenerator.dm b/code/datums/mapgen/CaveGenerator.dm
index 48df6e164fb..754b8755545 100644
--- a/code/datums/mapgen/CaveGenerator.dm
+++ b/code/datums/mapgen/CaveGenerator.dm
@@ -55,7 +55,7 @@
/mob/living/basic/mining/basilisk = 4,
/mob/living/basic/mining/goldgrub = 1,
/mob/living/basic/mining/goliath/ancient = 5,
- /mob/living/simple_animal/hostile/asteroid/hivelord = 3,
+ /mob/living/basic/mining/hivelord = 3,
)
mob_spawn_list = expand_weights(weighted_mob_spawn_list)
mob_spawn_no_mega_list = expand_weights(weighted_mob_spawn_list - SPAWN_MEGAFAUNA)
@@ -116,8 +116,8 @@
var/start_time = REALTIMEOFDAY
- for(var/turf/turf as anything in turfs)
- if(!(turf.type in open_turf_types)) //only put stuff on open turfs we generated, so closed walls and rivers and stuff are skipped
+ for(var/turf/target_turf as anything in turfs)
+ if(!(target_turf.type in open_turf_types)) //only put stuff on open turfs we generated, so closed walls and rivers and stuff are skipped
continue
// If we've spawned something yet
@@ -127,22 +127,24 @@
//FLORA SPAWNING HERE
if(flora_allowed && prob(flora_spawn_chance))
var/flora_type = pick(flora_spawn_list)
- new flora_type(turf)
+ new flora_type(target_turf)
spawned_something = TRUE
//FEATURE SPAWNING HERE
- if(feature_allowed && prob(feature_spawn_chance))
+ //we may have generated something from the flora list on the target turf, so let's not place
+ //a feature here if that's the case (because it would look stupid)
+ if(feature_allowed && !spawned_something && prob(feature_spawn_chance))
var/can_spawn = TRUE
var/atom/picked_feature = pick(feature_spawn_list)
- for(var/obj/structure/existing_feature in range(7, turf))
+ for(var/obj/structure/existing_feature in range(7, target_turf))
if(istype(existing_feature, picked_feature))
can_spawn = FALSE
break
if(can_spawn)
- new picked_feature(turf)
+ new picked_feature(target_turf)
spawned_something = TRUE
//MOB SPAWNING HERE
@@ -161,12 +163,12 @@
// prevents tendrils spawning in each other's collapse range
if(ispath(picked_mob, /obj/structure/spawner/lavaland))
- for(var/obj/structure/spawner/lavaland/spawn_blocker in range(2, turf))
+ for(var/obj/structure/spawner/lavaland/spawn_blocker in range(2, target_turf))
can_spawn = FALSE
break
// if the random is not a tendril (hopefully meaning it is a mob), avoid spawning if there's another one within 12 tiles
else
- var/list/things_in_range = range(12, turf)
+ var/list/things_in_range = range(12, target_turf)
for(var/mob/living/mob_blocker in things_in_range)
if(ismining(mob_blocker))
can_spawn = FALSE
@@ -176,7 +178,7 @@
can_spawn = can_spawn && !(locate(/obj/effect/spawner/random/lavaland_mob) in things_in_range)
//if there's a megafauna within standard view don't spawn anything at all (This isn't really consistent, I don't know why we do this. you do you tho)
if(can_spawn)
- for(var/mob/living/simple_animal/hostile/megafauna/found_fauna in range(7, turf))
+ for(var/mob/living/simple_animal/hostile/megafauna/found_fauna in range(7, target_turf))
can_spawn = FALSE
break
@@ -185,7 +187,7 @@
weighted_megafauna_spawn_list.Remove(picked_mob)
megafauna_spawn_list = expand_weights(weighted_megafauna_spawn_list)
megas_allowed = megas_allowed && length(megafauna_spawn_list)
- new picked_mob(turf)
+ new picked_mob(target_turf)
spawned_something = TRUE
CHECK_TICK
diff --git a/code/datums/mapgen/Cavegens/IcemoonCaves.dm b/code/datums/mapgen/Cavegens/IcemoonCaves.dm
index 89a153aedd7..7d7437ccda6 100644
--- a/code/datums/mapgen/Cavegens/IcemoonCaves.dm
+++ b/code/datums/mapgen/Cavegens/IcemoonCaves.dm
@@ -4,9 +4,9 @@
weighted_mob_spawn_list = list(
+ /mob/living/basic/mining/legion/snow = 50,
/mob/living/basic/mining/lobstrosity = 15,
/mob/living/basic/mining/goldgrub = 10,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 50,
/mob/living/simple_animal/hostile/asteroid/polarbear = 30,
/mob/living/simple_animal/hostile/asteroid/wolf = 50,
/obj/structure/spawner/ice_moon = 3,
@@ -63,7 +63,7 @@
weighted_mob_spawn_list = list(
SPAWN_MEGAFAUNA = 1,
/mob/living/basic/mining/ice_whelp = 60,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 100,
+ /mob/living/basic/mining/legion/snow = 100,
/mob/living/simple_animal/hostile/asteroid/ice_demon = 100,
/obj/structure/spawner/ice_moon/demonic_portal = 6,
/obj/structure/spawner/ice_moon/demonic_portal/snowlegion = 6,
diff --git a/code/datums/martial/boxing.dm b/code/datums/martial/boxing.dm
index 720bda243b9..9ba1a53d40c 100644
--- a/code/datums/martial/boxing.dm
+++ b/code/datums/martial/boxing.dm
@@ -67,6 +67,15 @@
/obj/item/clothing/gloves/boxing
var/datum/martial_art/boxing/style = new
+/obj/item/clothing/gloves/boxing/Initialize(mapload)
+ . = ..()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/extendohand_l, /datum/crafting_recipe/extendohand_r)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/clothing/gloves/boxing/equipped(mob/user, slot)
..()
// boxing requires human
diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm
index a5aa648ecee..53bcce6c6ff 100644
--- a/code/datums/mood_events/generic_negative_events.dm
+++ b/code/datums/mood_events/generic_negative_events.dm
@@ -167,6 +167,9 @@
mood_change = -4
timeout = 2 MINUTES
+/datum/mood_event/healsbadman/long_term
+ timeout = 10 MINUTES
+
/datum/mood_event/jittery
description = "I'm nervous and on edge and I can't stand still!!"
mood_change = -2
diff --git a/code/datums/mutations/antenna.dm b/code/datums/mutations/antenna.dm
index bc5026ab148..b71f66c0fa6 100644
--- a/code/datums/mutations/antenna.dm
+++ b/code/datums/mutations/antenna.dm
@@ -91,32 +91,11 @@
// chance to alert the read-ee
to_chat(cast_on, span_danger("You feel something foreign enter your mind."))
- var/list/recent_speech = list()
- var/list/say_log = list()
- var/log_source = cast_on.logging
- //this whole loop puts the read-ee's say logs into say_log in an easy to access way
- for(var/log_type in log_source)
- var/nlog_type = text2num(log_type)
- if(nlog_type & LOG_SAY)
- var/list/reversed = log_source[log_type]
- if(islist(reversed))
- say_log = reverse_range(reversed.Copy())
- break
-
- for(var/spoken_memory in say_log)
- //up to 3 random lines of speech, favoring more recent speech
- if(length(recent_speech) >= 3)
- break
- if(prob(50))
- continue
- // log messages with tags like telepathy are displayed like "(Telepathy to Ckey/(target)) "greetings"""
- // by splitting the text by using a " delimiter, we can grab JUST the greetings part
- recent_speech[spoken_memory] = splittext(say_log[spoken_memory], "\"", 1, 0, TRUE)[3]
-
+ var/list/recent_speech = cast_on.copy_recent_speech(copy_amount = 3, line_chance = 50)
if(length(recent_speech))
to_chat(owner, span_boldnotice("You catch some drifting memories of their past conversations..."))
for(var/spoken_memory in recent_speech)
- to_chat(owner, span_notice("[recent_speech[spoken_memory]]"))
+ to_chat(owner, span_notice("[spoken_memory]"))
if(iscarbon(cast_on))
var/mob/living/carbon/carbon_cast_on = cast_on
diff --git a/code/datums/mutations/touch.dm b/code/datums/mutations/touch.dm
index 1f1cefe1cbe..3f798ba52b2 100644
--- a/code/datums/mutations/touch.dm
+++ b/code/datums/mutations/touch.dm
@@ -38,7 +38,7 @@
///This var decides if the spell should chain, dictated by presence of power chromosome
var/chain = FALSE
///Affects damage, should do about 1 per limb
- var/zap_power = 7500
+ var/zap_power = 3e6
///Range of tesla shock bounces
var/zap_range = 7
///flags that dictate what the tesla shock can interact with, Can only damage mobs, Cannot damage machines or generate energy
diff --git a/code/datums/quirks/negative_quirks/prosthetic_limb.dm b/code/datums/quirks/negative_quirks/prosthetic_limb.dm
index f6f0e304a6d..e7ea4d75788 100644
--- a/code/datums/quirks/negative_quirks/prosthetic_limb.dm
+++ b/code/datums/quirks/negative_quirks/prosthetic_limb.dm
@@ -3,9 +3,8 @@
desc = "An accident caused you to lose one of your limbs. Because of this, you now have a surplus prosthetic!"
icon = "tg-prosthetic-leg"
value = -3
- medical_record_text = "During physical examination, patient was found to have a low-budget prosthetic limb."
hardcore_value = 3
- quirk_flags = QUIRK_HUMAN_ONLY // while this technically changes appearance, we don't want it to be shown on the dummy because it's randomized at roundstart
+ quirk_flags = QUIRK_HUMAN_ONLY | QUIRK_CHANGES_APPEARANCE
mail_goodies = list(/obj/item/weldingtool/mini, /obj/item/stack/cable_coil/five)
/// The slot to replace, in string form
var/slot_string = "limb"
@@ -13,28 +12,20 @@
var/obj/item/bodypart/old_limb
/datum/quirk/prosthetic_limb/add_unique(client/client_source)
- var/limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
+ var/limb_type = GLOB.limb_choice[client_source?.prefs?.read_preference(/datum/preference/choiced/prosthetic)]
+ if(isnull(limb_type)) //Client gone or they chose a random prosthetic
+ limb_type = GLOB.limb_choice[pick(GLOB.limb_choice)]
+
var/mob/living/carbon/human/human_holder = quirk_holder
- var/obj/item/bodypart/prosthetic
- switch(limb_slot)
- if(BODY_ZONE_L_ARM)
- prosthetic = new /obj/item/bodypart/arm/left/robot/surplus
- slot_string = "left arm"
- if(BODY_ZONE_R_ARM)
- prosthetic = new /obj/item/bodypart/arm/right/robot/surplus
- slot_string = "right arm"
- if(BODY_ZONE_L_LEG)
- prosthetic = new /obj/item/bodypart/leg/left/robot/surplus
- slot_string = "left leg"
- if(BODY_ZONE_R_LEG)
- prosthetic = new /obj/item/bodypart/leg/right/robot/surplus
- slot_string = "right leg"
- medical_record_text = "During physical examination, patient was found to have a low-budget prosthetic [slot_string]."
- old_limb = human_holder.return_and_replace_bodypart(prosthetic, special = TRUE)
+ var/obj/item/bodypart/surplus = new limb_type()
+ slot_string = "[surplus.plaintext_zone]"
+
+ medical_record_text = "Patient uses a low-budget prosthetic on the [slot_string]."
+ old_limb = human_holder.return_and_replace_bodypart(surplus, special = TRUE)
/datum/quirk/prosthetic_limb/post_add()
to_chat(quirk_holder, span_boldannounce("Your [slot_string] has been replaced with a surplus prosthetic. It is fragile and will easily come apart under duress. Additionally, \
- you need to use a welding tool and cables to repair it, instead of bruise packs and ointment."))
+ you need to use a welding tool and cables to repair it, instead of sutures and regenerative meshes."))
/datum/quirk/prosthetic_limb/remove()
var/mob/living/carbon/human/human_holder = quirk_holder
diff --git a/code/datums/records/manifest.dm b/code/datums/records/manifest.dm
index 13061218b51..7b43b7644ef 100644
--- a/code/datums/records/manifest.dm
+++ b/code/datums/records/manifest.dm
@@ -111,6 +111,8 @@ GLOBAL_DATUM_INIT(manifest, /datum/manifest, new)
person_gender = "Male"
if(person.gender == "female")
person_gender = "Female"
+ var/datum/dna/record_dna = new()
+ person.dna.copy_dna(record_dna)
// SKYRAT EDIT ADDITION BEGIN - ALTERNATIVE_JOB_TITLES
// The alt job title, if user picked one, or the default
@@ -119,32 +121,32 @@ GLOBAL_DATUM_INIT(manifest, /datum/manifest, new)
var/datum/record/locked/lockfile = new(
age = person.age,
- blood_type = person.dna.blood_type,
+ blood_type = record_dna.blood_type,
character_appearance = character_appearance,
- dna_string = person.dna.unique_enzymes,
- fingerprint = md5(person.dna.unique_identity),
+ dna_string = record_dna.unique_enzymes,
+ fingerprint = md5(record_dna.unique_identity),
gender = person_gender,
initial_rank = assignment,
name = person.real_name,
rank = chosen_assignment, // SKYRAT EDIT - Alt job titles - ORIGINAL: rank = assignment,
- species = person.dna.species.name,
+ species = record_dna.species.name,
trim = assignment,
// Locked specifics
- dna_ref = person.dna,
+ locked_dna = record_dna,
mind_ref = person.mind,
)
new /datum/record/crew(
age = person.age,
- blood_type = person.dna.blood_type,
+ blood_type = record_dna.blood_type,
character_appearance = character_appearance,
- dna_string = person.dna.unique_enzymes,
- fingerprint = md5(person.dna.unique_identity),
+ dna_string = record_dna.unique_enzymes,
+ fingerprint = md5(record_dna.unique_identity),
gender = person_gender,
initial_rank = assignment,
name = person.real_name,
rank = chosen_assignment, // SKYRAT EDIT - Alt job titles - ORIGINAL: rank = assignment,
- species = person.dna.species.name,
+ species = record_dna.species.name,
trim = assignment,
// Crew specific
lock_ref = REF(lockfile),
diff --git a/code/datums/records/record.dm b/code/datums/records/record.dm
index 67fce2f49a4..276865115e4 100644
--- a/code/datums/records/record.dm
+++ b/code/datums/records/record.dm
@@ -24,6 +24,8 @@
var/species
/// The character's ID trim
var/trim
+ /// The character's voice, if they have one.
+ var/voice
/datum/record/New(
age = 18,
@@ -37,6 +39,7 @@
rank = "Unassigned",
species = "Human",
trim = "Unassigned",
+ voice = "?????",
)
src.age = age
src.blood_type = blood_type
@@ -138,9 +141,9 @@
*/
/datum/record/locked
/// Mob's dna
- var/datum/dna/dna_ref
+ var/datum/dna/locked_dna
/// Mind datum
- var/datum/mind/mind_ref
+ var/datum/weakref/mind_ref
/// Typepath of species used by player, for usage in respawning via records
var/species_type
@@ -157,13 +160,13 @@
species = "Human",
trim = "Unassigned",
/// Locked specific
- datum/dna/dna_ref,
+ datum/dna/locked_dna,
datum/mind/mind_ref,
)
. = ..()
- src.dna_ref = dna_ref
- src.mind_ref = mind_ref
- species_type = dna_ref.species.type
+ src.locked_dna = locked_dna
+ src.mind_ref = WEAKREF(mind_ref)
+ species_type = locked_dna.species.type
GLOB.manifest.locked += src
diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm
index b9747d54acc..cb0b55be059 100644
--- a/code/datums/status_effects/buffs.dm
+++ b/code/datums/status_effects/buffs.dm
@@ -265,10 +265,10 @@
/datum/status_effect/hippocratic_oath/proc/consume_owner()
owner.visible_message(span_notice("[owner]'s soul is absorbed into the rod, relieving the previous snake of its duty."))
var/list/chems = list(/datum/reagent/medicine/sal_acid, /datum/reagent/medicine/c2/convermol, /datum/reagent/medicine/oxandrolone)
- var/mob/living/simple_animal/hostile/retaliate/snake/healSnake = new(owner.loc, pick(chems))
- healSnake.name = "Asclepius's Snake"
- healSnake.real_name = "Asclepius's Snake"
- healSnake.desc = "A mystical snake previously trapped upon the Rod of Asclepius, now freed of its burden. Unlike the average snake, its bites contain chemicals with minor healing properties."
+ var/mob/living/basic/snake/spawned = new(owner.loc, pick(chems))
+ spawned.name = "Asclepius's Snake"
+ spawned.real_name = "Asclepius's Snake"
+ spawned.desc = "A mystical snake previously trapped upon the Rod of Asclepius, now freed of its burden. Unlike the average snake, its bites contain chemicals with minor healing properties."
new /obj/effect/decal/cleanable/ash(owner.loc)
new /obj/item/rod_of_asclepius(owner.loc)
owner.investigate_log("has been consumed by the Rod of Asclepius.", INVESTIGATE_DEATHS)
diff --git a/code/datums/status_effects/debuffs/cyborg.dm b/code/datums/status_effects/debuffs/cyborg.dm
new file mode 100644
index 00000000000..0f95b494197
--- /dev/null
+++ b/code/datums/status_effects/debuffs/cyborg.dm
@@ -0,0 +1,22 @@
+/// Reduce a cyborg's speed when you throw things at it
+/datum/status_effect/borg_throw_slow
+ id = "borg_throw_slowdown"
+ alert_type = /atom/movable/screen/alert/status_effect/borg_throw_slow
+ duration = 3 SECONDS
+ status_type = STATUS_EFFECT_REPLACE
+
+/datum/status_effect/borg_throw_slow/on_apply()
+ . = ..()
+ owner.add_movespeed_modifier(/datum/movespeed_modifier/borg_throw, update = TRUE)
+
+/datum/status_effect/borg_throw_slow/on_remove()
+ . = ..()
+ owner.remove_movespeed_modifier(/datum/movespeed_modifier/borg_throw, update = TRUE)
+
+/atom/movable/screen/alert/status_effect/borg_throw_slow
+ name = "Percussive Maintenance"
+ desc = "A sudden impact has triggered your collision avoidance routines, reducing movement speed."
+ icon_state = "weaken"
+
+/datum/movespeed_modifier/borg_throw
+ multiplicative_slowdown = 0.9
diff --git a/code/datums/votes/map_vote.dm b/code/datums/votes/map_vote.dm
index 745e7c6f7af..323ee29ccc2 100644
--- a/code/datums/votes/map_vote.dm
+++ b/code/datums/votes/map_vote.dm
@@ -20,7 +20,7 @@
/datum/vote/map_vote/create_vote()
. = ..()
check_population(should_key_choices = FALSE)
- if((length(choices) == 1) && EMERGENCY_ESCAPED_OR_ENDGAMED) // Only one choice, no need to vote. Let's just auto-rotate it to the only remaining map because it would just happen anyways.
+ if(length(choices) == 1) // Only one choice, no need to vote. Let's just auto-rotate it to the only remaining map because it would just happen anyways.
var/de_facto_winner = choices[1]
var/datum/map_config/change_me_out = global.config.maplist[de_facto_winner]
SSmapping.changemap(change_me_out)
@@ -118,3 +118,12 @@
SSmapping.map_voted = TRUE
if(SSmapping.map_vote_rocked)
SSmapping.map_vote_rocked = FALSE
+
+/proc/revert_map_vote()
+ var/datum/map_config/override_map = SSmapping.config
+ if(isnull(override_map))
+ return
+
+ SSmapping.changemap(override_map)
+ log_game("The next map has been reset to [override_map.map_name].")
+ send_to_playing_players(span_boldannounce("The next map is: [override_map.map_name]."))
diff --git a/code/datums/votes/restart_vote.dm b/code/datums/votes/restart_vote.dm
index 24d38f35396..987d5b87eb3 100644
--- a/code/datums/votes/restart_vote.dm
+++ b/code/datums/votes/restart_vote.dm
@@ -67,7 +67,14 @@
message_admins("A restart vote has passed, but there are active admins on with +SERVER, so it has been canceled. If you wish, you may restart the server.")
return
- SSticker.Reboot("Restart vote successful.", "restart vote", 1)
+ // If there was a previous map vote, we revert the change.
+ if(!isnull(SSmapping.next_map_config))
+ log_game("The next map has been reset due to successful restart vote.")
+ send_to_playing_players(span_boldannounce("The next map has been reset due to successful restart vote."))
+ revert_map_vote()
+
+ SSticker.force_ending = FORCE_END_ROUND
+ log_game("End round forced by successful restart vote.")
return
CRASH("[type] wasn't passed a valid winning choice. (Got: [winning_option || "null"])")
diff --git a/code/datums/wounds/scars/_scars.dm b/code/datums/wounds/scars/_scars.dm
index 774d8cc5265..e650899be29 100644
--- a/code/datums/wounds/scars/_scars.dm
+++ b/code/datums/wounds/scars/_scars.dm
@@ -181,7 +181,7 @@
if((human_victim.wear_mask && (human_victim.wear_mask.flags_inv & HIDEFACE)) || (human_victim.head && (human_victim.head.flags_inv & HIDEFACE)))
return FALSE
else if(limb.scars_covered_by_clothes)
- var/num_covers = LAZYLEN(human_victim.clothingonpart(limb))
+ var/num_covers = LAZYLEN(human_victim.get_clothing_on_part(limb))
if(num_covers + get_dist(viewer, victim) >= visibility)
return FALSE
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 29c5ea6e4df..4912a69f7b8 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -705,6 +705,7 @@
. = list()
SEND_SIGNAL(src, COMSIG_ATOM_EXAMINE_MORE, user, .)
+ SEND_SIGNAL(user, COMSIG_MOB_EXAMINING_MORE, src, .)
/// Wrapper for _update_appearance that is only called when APPEARANCE_SUCCESS_TRACKING is defined
#ifdef APPEARANCE_SUCCESS_TRACKING
diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm
index 26dfcb4be76..6208df36de1 100644
--- a/code/game/gamemodes/dynamic/dynamic.dm
+++ b/code/game/gamemodes/dynamic/dynamic.dm
@@ -468,8 +468,8 @@ GLOBAL_LIST_EMPTY(dynamic_station_traits)
for(var/job in job_prefs)
var/priority = job_prefs[job]
job_data += "[job]: [SSjob.job_priority_level_to_string(priority)]"
- to_chat(player, span_danger("You were unable to qualify for any roundstart antagonist role because you could not qualify for any of the roundstart jobs you were trying to qualify for, along with 'return to lobby if job is unavailable' enabled."))
- log_admin("[player.ckey] failed to qualify for any job and has [player.client.prefs.be_special.len] antag preferences enabled. They will be unable to qualify for any roundstart antagonist role. These are their job preferences - [job_data.Join(" | ")]")
+ to_chat(player, span_danger("You were unable to qualify for any roundstart antagonist role this round because your job preferences presented a high chance of all of your selected jobs being unavailable, along with 'return to lobby if job is unavailable' enabled. Increase the number of roles set to medium or low priority to reduce the chances of this happening."))
+ log_admin("[player.ckey] failed to qualify for any roundstart antagonist role because their job preferences presented a high chance of all of their selected jobs being unavailable, along with 'return to lobby if job is unavailable' enabled and has [player.client.prefs.be_special.len] antag preferences enabled. They will be unable to qualify for any roundstart antagonist role. These are their job preferences - [job_data.Join(" | ")]")
else
roundstart_pop_ready++
candidates.Add(player)
@@ -639,8 +639,10 @@ GLOBAL_LIST_EMPTY(dynamic_station_traits)
if(rule.persistent)
current_rules += rule
new_snapshot(rule)
+ rule.forget_startup()
return TRUE
rule.clean_up() // Refund threat, delete teams and so on.
+ rule.forget_startup()
executed_rules -= rule
stack_trace("The starting rule \"[rule.name]\" failed to execute.")
return FALSE
@@ -688,9 +690,11 @@ GLOBAL_LIST_EMPTY(dynamic_station_traits)
executed_rules += new_rule
if (new_rule.persistent)
current_rules += new_rule
+ new_rule.forget_startup()
return TRUE
else if (forced)
log_dynamic("The ruleset [new_rule.name] couldn't be executed due to lack of elligible players.")
+ new_rule.forget_startup()
return FALSE
/datum/game_mode/dynamic/process()
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm
index faefbbe9426..a1c4c9232e2 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm
@@ -167,6 +167,14 @@
GLOB.pre_setup_antags -= M
return TRUE
+/// Rulesets can be reused, so when we're done setting one up we want to wipe its memory of the people it was selecting over
+/// This isn't Destroy we aren't deleting it here, rulesets free when nothing holds a ref. This is just to prevent hung refs.
+/datum/dynamic_ruleset/proc/forget_startup()
+ SHOULD_CALL_PARENT(TRUE)
+ candidates = list()
+ assigned = list()
+ antag_datum = null
+
/// Here you can perform any additional checks you want. (such as checking the map etc)
/// Remember that on roundstart no one knows what their job is at this point.
/// IMPORTANT: If ready() returns TRUE, that means pre_execute() or execute() should never fail!
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
index 99aabf400d2..91f82f29f1c 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
@@ -21,6 +21,13 @@
/// Abstract root value
var/abstract_type = /datum/dynamic_ruleset/midround
+/datum/dynamic_ruleset/midround/forget_startup()
+ living_players = list()
+ living_antags = list()
+ dead_players = list()
+ list_observers = list()
+ return ..()
+
/datum/dynamic_ruleset/midround/from_ghosts
weight = 0
required_type = /mob/dead/observer
@@ -370,8 +377,6 @@
flags = HIGH_IMPACT_RULESET
var/list/operative_cap = list(2,2,3,3,4,5,5,5,5,5)
- /// The nuke ops team datum.
- var/datum/team/nuclear/nuke_team
/datum/dynamic_ruleset/midround/from_ghosts/nuclear/acceptable(population=0, threat=0)
if (locate(/datum/dynamic_ruleset/roundstart/nuclear) in mode.executed_rules)
@@ -397,7 +402,6 @@
new_character.mind.special_role = ROLE_NUCLEAR_OPERATIVE
if(index == 1)
var/datum/antagonist/nukeop/leader/leader_antag_datum = new()
- nuke_team = leader_antag_datum.nuke_team
new_character.mind.add_antag_datum(leader_antag_datum)
return
return ..()
@@ -483,6 +487,10 @@
repeatable = TRUE
var/list/vents = list()
+/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/forget_startup()
+ vents = list()
+ return ..()
+
/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/execute()
// 50% chance of being incremented by one
required_candidates += prob(50)
@@ -562,6 +570,10 @@
repeatable = TRUE
var/list/spawn_locs = list()
+/datum/dynamic_ruleset/midround/from_ghosts/space_dragon/forget_startup()
+ spawn_locs = list()
+ return ..()
+
/datum/dynamic_ruleset/midround/from_ghosts/space_dragon/execute()
for(var/obj/effect/landmark/carpspawn/C in GLOB.landmarks_list)
spawn_locs += (C.loc)
@@ -600,6 +612,10 @@
var/datum/team/abductor_team/new_team
+/datum/dynamic_ruleset/midround/from_ghosts/abductors/forget_startup()
+ new_team = null
+ return ..()
+
/datum/dynamic_ruleset/midround/from_ghosts/abductors/ready(forced = FALSE)
if (required_candidates > (dead_players.len + list_observers.len))
return FALSE
@@ -632,6 +648,10 @@
var/list/spawn_locs = list()
+/datum/dynamic_ruleset/midround/from_ghosts/space_ninja/forget_startup()
+ spawn_locs = list()
+ return ..()
+
/datum/dynamic_ruleset/midround/from_ghosts/space_ninja/execute()
for(var/obj/effect/landmark/carpspawn/carp_spawn in GLOB.landmarks_list)
if(!isturf(carp_spawn.loc))
@@ -686,6 +706,10 @@
var/need_extra_spawns_value = 15
var/list/spawn_locs = list()
+/datum/dynamic_ruleset/midround/from_ghosts/revenant/forget_startup()
+ spawn_locs = list()
+ return ..()
+
/datum/dynamic_ruleset/midround/from_ghosts/revenant/acceptable(population=0, threat=0)
if(GLOB.dead_mob_list.len < dead_mobs_required)
return FALSE
@@ -857,6 +881,10 @@
repeatable = TRUE
var/list/possible_spawns = list() ///places the antag can spawn
+/datum/dynamic_ruleset/midround/from_ghosts/paradox_clone/forget_startup()
+ possible_spawns = list()
+ return ..()
+
/datum/dynamic_ruleset/midround/from_ghosts/paradox_clone/execute()
possible_spawns += find_maintenance_spawn(atmos_sensitive = TRUE, require_darkness = FALSE)
if(!possible_spawns.len)
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
index df078c462d9..a90eba738c1 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
@@ -121,6 +121,10 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE)
var/list/datum/team/brother_team/pre_brother_teams = list()
var/const/min_team_size = 2
+/datum/dynamic_ruleset/roundstart/traitorbro/forget_startup()
+ pre_brother_teams = list()
+ return ..()
+
/datum/dynamic_ruleset/roundstart/traitorbro/pre_execute(population)
. = ..()
var/num_teams = (get_antag_cap(population)/min_team_size) * (scaled_times + 1) // 1 team per scaling
diff --git a/code/game/gamemodes/dynamic/ruleset_picking.dm b/code/game/gamemodes/dynamic/ruleset_picking.dm
index 4922d7355ce..d6e2fd6b1f4 100644
--- a/code/game/gamemodes/dynamic/ruleset_picking.dm
+++ b/code/game/gamemodes/dynamic/ruleset_picking.dm
@@ -118,11 +118,12 @@
message_admins("[key_name(M)] joined the station, and was selected by the [rule.name] ruleset.")
log_dynamic("[key_name(M)] joined the station, and was selected by the [rule.name] ruleset.")
executed_rules += rule
- rule.candidates.Cut()
if (rule.persistent)
current_rules += rule
new_snapshot(rule)
+ rule.forget_startup()
return TRUE
+ rule.forget_startup()
rule.clean_up()
stack_trace("The [rule.ruletype] rule \"[rule.name]\" failed to execute.")
return FALSE
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 00488ba1dfb..bdefee42c3e 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -236,18 +236,46 @@ GLOBAL_LIST_EMPTY(objectives) //SKYRAT EDIT ADDITION
/datum/objective/assassinate/admin_edit(mob/admin)
admin_simple_target_pick(admin)
+#define DISCONNECT_GRACE_TIME (2 MINUTES)
+#define DISCONNECT_GRACE_WARNING_TIME (1 MINUTES)
+
/datum/objective/mutiny
name = "mutiny"
martyr_compatible = 1
var/target_role_type = FALSE
+ /// Not primarily used as a cooldown but a timer to give a little bit more of a chance for the player to reconnect.
+ COOLDOWN_DECLARE(disconnect_timer)
+ /// Whether admins have been warned about the potentially AFK player
+ var/warned_admins = FALSE
+/datum/objective/mutiny/proc/warn_admins()
+ message_admins("[ADMIN_LOOKUPFLW(target.current)] has gone AFK with a mutiny objective that involves them. They only have [COOLDOWN_TIMELEFT(src, disconnect_timer) / 10] seconds remaining before they are treated as if they were dead.")
/datum/objective/mutiny/check_completion()
- if(!target || !considered_alive(target) || considered_afk(target) || considered_exiled(target))
+ if(!target || !considered_alive(target) || considered_exiled(target))
return TRUE
+
+ if(considered_afk(target))
+ if(!COOLDOWN_STARTED(src, disconnect_timer))
+ COOLDOWN_START(src, disconnect_timer, DISCONNECT_GRACE_TIME)
+ warn_admins()
+ else if(COOLDOWN_FINISHED(src, disconnect_timer))
+ return TRUE
+ else if(COOLDOWN_TIMELEFT(src, disconnect_timer) <= DISCONNECT_GRACE_WARNING_TIME && !warned_admins)
+ warned_admins = TRUE
+ warn_admins()
+ else
+ COOLDOWN_RESET(src, disconnect_timer)
+ warned_admins = FALSE
+
var/turf/T = get_turf(target.current)
return !T || !is_station_level(T.z)
+#undef DISCONNECT_GRACE_TIME
+#undef DISCONNECT_GRACE_WARNING_TIME
+
+
+
/datum/objective/mutiny/update_explanation_text()
..()
if(target?.current)
diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm
index b6327480399..fde5c89b88d 100644
--- a/code/game/machinery/_machinery.dm
+++ b/code/game/machinery/_machinery.dm
@@ -927,6 +927,7 @@
wrench.play_tool_sound(src, 50)
setDir(turn(dir,-90))
to_chat(user, span_notice("You rotate [src]."))
+ SEND_SIGNAL(src, COMSIG_MACHINERY_DEFAULT_ROTATE_WRENCH, user, wrench)
return TRUE
/obj/machinery/proc/exchange_parts(mob/user, obj/item/storage/part_replacer/replacer_tool)
@@ -1122,10 +1123,10 @@
if(prob(85) && (zap_flags & ZAP_MACHINE_EXPLOSIVE) && !(resistance_flags & INDESTRUCTIBLE))
explosion(src, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 4, flame_range = 2, adminlog = FALSE, smoke = FALSE)
else if(zap_flags & ZAP_OBJ_DAMAGE)
- take_damage(power * 0.0005, BURN, ENERGY)
+ take_damage(power * 6.25e-7, BURN, ENERGY)
if(prob(40))
emp_act(EMP_LIGHT)
- power -= power * 0.0005
+ power -= power * 5e-4
return ..()
/obj/machinery/proc/adjust_item_drop_location(atom/movable/dropped_atom) // Adjust item drop location to a 3x3 grid inside the tile, returns slot id from 0 to 8
diff --git a/code/game/machinery/airlock_control.dm b/code/game/machinery/airlock_control.dm
index 4c3532e3616..f4d1b29da18 100644
--- a/code/game/machinery/airlock_control.dm
+++ b/code/game/machinery/airlock_control.dm
@@ -6,10 +6,6 @@
var/airlock_state
var/frequency
-/obj/machinery/door/airlock/Initialize(mapload)
- . = ..()
- RegisterSignal(SSdcs, COMSIG_GLOB_GREY_TIDE, PROC_REF(grey_tide))
-
/// Forces the airlock to unbolt and open
/obj/machinery/door/airlock/proc/secure_open()
locked = FALSE
@@ -35,17 +31,6 @@
locked = FALSE
return ..()
-/obj/machinery/door/airlock/proc/grey_tide(datum/source, list/grey_tide_areas)
- SIGNAL_HANDLER
-
- if(!is_station_level(z) || critical_machine)
- return //Skip doors in critical positions, such as the SM chamber.
-
- for(var/area_type in grey_tide_areas)
- if(!istype(get_area(src), area_type))
- continue
- INVOKE_ASYNC(src, PROC_REF(prison_open)) //Sleep gets called further down in open(), so we have to invoke async
-
/obj/machinery/airlock_sensor
icon = 'icons/obj/machines/wallmounts.dmi'
icon_state = "airlock_sensor_off"
diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm
index 4ec567a95d6..c433565dbf8 100644
--- a/code/game/machinery/computer/crew.dm
+++ b/code/game/machinery/computer/crew.dm
@@ -262,8 +262,9 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
// SKYRAT EDIT END
// Binary living/dead status
+ // Current status
if (sensor_mode >= SENSOR_LIVING)
- entry["life_status"] = (tracked_living_mob.stat != DEAD)
+ entry["life_status"] = tracked_living_mob.stat
// Damage
if (sensor_mode >= SENSOR_VITALS)
diff --git a/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm b/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm
index 57067db47f6..96c33871a40 100644
--- a/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm
+++ b/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm
@@ -133,7 +133,7 @@
. = ..()
if(prob(5))
owner.emote("squeaks")
- playsound(owner, 'sound/effects/mousesqueek.ogg', 100)
+ playsound(owner, 'sound/creatures/mousesqueek.ogg', 100)
#undef RAT_ORGAN_COLOR
#undef RAT_SCLERA_COLOR
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 2786ed0f769..9d18b7ecb85 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -191,12 +191,23 @@
diag_hud_set_electrified()
- RegisterSignal(src, COMSIG_MACHINERY_BROKEN, PROC_REF(on_break))
-
// Click on the floor to close airlocks
AddComponent(/datum/component/redirect_attack_hand_from_turf)
- return INITIALIZE_HINT_LATELOAD
+ RegisterSignal(src, COMSIG_MACHINERY_BROKEN, PROC_REF(on_break))
+
+ RegisterSignal(SSdcs, COMSIG_GLOB_GREY_TIDE, PROC_REF(grey_tide))
+
+/obj/machinery/door/airlock/proc/grey_tide(datum/source, list/grey_tide_areas)
+ SIGNAL_HANDLER
+
+ if(!is_station_level(z) || critical_machine)
+ return //Skip doors in critical positions, such as the SM chamber.
+
+ for(var/area_type in grey_tide_areas)
+ if(!istype(get_area(src), area_type))
+ continue
+ INVOKE_ASYNC(src, PROC_REF(prison_open)) //Sleep gets called further down in open(), so we have to invoke async
/obj/machinery/door/airlock/connect_to_shuttle(mapload, obj/docking_port/mobile/port, obj/docking_port/stationary/dock)
if(id_tag)
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index d5d0e9c732e..15c740a31e4 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -138,6 +138,9 @@
storage_type = /obj/item/tank/jetpack/oxygen/harness
mod_type = /obj/item/mod/control/pre_equipped/nuclear
+/obj/machinery/suit_storage_unit/syndicate/lavaland
+ mod_type = /obj/item/mod/control/pre_equipped/nuclear/no_jetpack
+
/obj/machinery/suit_storage_unit/interdyne
mask_type = /obj/item/clothing/mask/gas/syndicate
storage_type = /obj/item/tank/jetpack/oxygen/harness
diff --git a/code/game/machinery/telecomms/computers/telemonitor.dm b/code/game/machinery/telecomms/computers/telemonitor.dm
index b862a6372b7..400d827f618 100644
--- a/code/game/machinery/telecomms/computers/telemonitor.dm
+++ b/code/game/machinery/telecomms/computers/telemonitor.dm
@@ -14,10 +14,10 @@
/// Current screen the user is viewing
var/screen = MAIN_VIEW
- /// The machines located by the computer
- var/list/machinelist = list()
- /// the currently selected machine
- var/obj/machinery/telecomms/SelectedMachine
+ /// Weakrefs of the machines located by the computer
+ var/list/machine_list = list()
+ /// Weakref of the currently selected tcomms machine
+ var/datum/weakref/selected_machine_ref
/// The network to probe
var/network = "NULL"
/// Error message to show
@@ -35,20 +35,26 @@
// --- Main Menu ---
if(MAIN_VIEW)
var/list/found_machinery = list()
- for(var/obj/machinery/telecomms/telecomms in machinelist)
+ for(var/datum/weakref/tcomms_ref in machine_list)
+ var/obj/machinery/telecomms/telecomms = tcomms_ref.resolve()
+ if(!telecomms)
+ machine_list -= tcomms_ref
+ continue
found_machinery += list(list("ref" = REF(telecomms), "name" = telecomms.name, "id" = telecomms.id))
data["machinery"] = found_machinery
// --- Viewing Machine ---
if(MACHINE_VIEW)
// Send selected machinery data
var/list/machine_out = list()
- machine_out["name"] = SelectedMachine.name
- // Get the linked machinery
- var/list/linked_machinery = list()
- for(var/obj/machinery/telecomms/T in SelectedMachine.links)
- linked_machinery += list(list("ref" = REF(T.id), "name" = T.name, "id" = T.id))
- machine_out["linked_machinery"] = linked_machinery
- data["machine"] = machine_out
+ var/obj/machinery/telecomms/selected = selected_machine_ref.resolve()
+ if(selected)
+ machine_out["name"] = selected.name
+ // Get the linked machinery
+ var/list/linked_machinery = list()
+ for(var/obj/machinery/telecomms/T in selected.links)
+ linked_machinery += list(list("ref" = REF(T.id), "name" = T.name, "id" = T.id))
+ machine_out["linked_machinery"] = linked_machinery
+ data["machine"] = machine_out
return data
/obj/machinery/computer/telecomms/monitor/ui_act(action, params)
@@ -67,7 +73,9 @@
error_message = "OPERATION FAILED: NETWORK ID TOO LONG."
return TRUE
- if(machinelist.len > 0)
+ list_clear_empty_weakrefs(machine_list)
+
+ if(machine_list.len > 0)
error_message = "OPERATION FAILED: CANNOT PROBE WHEN BUFFER FULL."
return TRUE
@@ -75,26 +83,30 @@
for(var/obj/machinery/telecomms/T in urange(25, src))
if(T.network == network)
- machinelist.Add(T)
- if(machinelist.len == 0)
+ machine_list += WEAKREF(T)
+ if(machine_list.len == 0)
error_message = "OPERATION FAILED: UNABLE TO LOCATE NETWORK ENTITIES IN [network]."
return TRUE
- error_message = "[machinelist.len] ENTITIES LOCATED & BUFFERED";
+ error_message = "[machine_list.len] ENTITIES LOCATED & BUFFERED";
return TRUE
if("flush_buffer")
- machinelist = list()
+ machine_list = list()
network = ""
return TRUE
if("view_machine")
- for(var/obj/machinery/telecomms/T in machinelist)
- if(T.id == params["id"])
- SelectedMachine = T
- if(!SelectedMachine)
+ for(var/datum/weakref/tcomms_ref in machine_list)
+ var/obj/machinery/telecomms/tcomms = tcomms_ref.resolve()
+ if(!tcomms)
+ machine_list -= tcomms_ref
+ continue
+ if(tcomms.id == params["id"])
+ selected_machine_ref = tcomms_ref
+ if(!selected_machine_ref)
error_message = "OPERATION FAILED: UNABLE TO LOCATE MACHINERY."
screen = MACHINE_VIEW
return TRUE
if("return_home")
- SelectedMachine = null
+ selected_machine_ref = null
screen = MAIN_VIEW
return TRUE
return TRUE
diff --git a/code/game/objects/effects/anomalies/anomalies_flux.dm b/code/game/objects/effects/anomalies/anomalies_flux.dm
index eee4319b352..2bb3ab28a1a 100644
--- a/code/game/objects/effects/anomalies/anomalies_flux.dm
+++ b/code/game/objects/effects/anomalies/anomalies_flux.dm
@@ -66,7 +66,7 @@
///range in whuich we zap
var/zap_range = 1
///strength of the zappy
- var/zap_power = 2500
+ var/zap_power = 1e6
///the zappy flags
var/zap_flags = ZAP_GENERATES_POWER | ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE
diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm
index 6a519650d10..daaddb00ce0 100644
--- a/code/game/objects/effects/decals/cleanable/misc.dm
+++ b/code/game/objects/effects/decals/cleanable/misc.dm
@@ -212,6 +212,10 @@
icon_state += "-old"
AddElement(/datum/element/swabable, CELL_LINE_TABLE_SLUDGE, CELL_VIRUS_TABLE_GENERIC, rand(2,4), 10)
+/obj/effect/decal/cleanable/vomit/old/black_bile
+ name = "black bile"
+ desc = "There's something wiggling in there..."
+ color = COLOR_DARK
/obj/effect/decal/cleanable/chem_pile
name = "chemical pile"
diff --git a/code/game/objects/effects/spawners/random/lavaland_mobs.dm b/code/game/objects/effects/spawners/random/lavaland_mobs.dm
index 8aa20cc90e7..7b4bec1f6a1 100644
--- a/code/game/objects/effects/spawners/random/lavaland_mobs.dm
+++ b/code/game/objects/effects/spawners/random/lavaland_mobs.dm
@@ -10,9 +10,9 @@
/mob/living/basic/mining/brimdemon = 1,
/mob/living/basic/mining/goldgrub = 1,
/mob/living/basic/mining/goliath = 1,
+ /mob/living/basic/mining/legion = 1,
/mob/living/basic/mining/lobstrosity/lava = 1,
/mob/living/basic/mining/watcher = 1,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion = 1,
)
/// Spawns random watcher variants during map generation
@@ -46,6 +46,6 @@
desc = "Chance to spawn a rare shiny version."
icon_state = "legion"
loot = list(
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion = 19,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/dwarf = 1,
+ /mob/living/basic/mining/legion = 19,
+ /mob/living/basic/mining/legion/dwarf = 1,
)
diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm
index aaef891ee4a..94e9cb674b2 100644
--- a/code/game/objects/items/cigs_lighters.dm
+++ b/code/game/objects/items/cigs_lighters.dm
@@ -358,6 +358,10 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(!istype(smoker) || smoker.get_item_by_slot(ITEM_SLOT_MASK) != loc)
reagents.remove_any(to_smoke)
return
+ else
+ if(src != smoker.wear_mask)
+ reagents.remove_any(to_smoke)
+ return
reagents.expose(smoker, INGEST, min(to_smoke / reagents.total_volume, 1))
var/obj/item/organ/internal/lungs/lungs = smoker.get_organ_slot(ORGAN_SLOT_LUNGS)
diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm
index e5b7144dc8c..dae27c175b4 100644
--- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm
@@ -822,7 +822,7 @@
/obj/item/circuitboard/machine/cryo_tube
name = "Cryotube"
greyscale_colors = CIRCUIT_COLOR_MEDICAL
- build_path = /obj/machinery/atmospherics/components/unary/cryo_cell
+ build_path = /obj/machinery/cryo_cell
req_components = list(
/datum/stock_part/matter_bin = 1,
/obj/item/stack/cable_coil = 1,
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index 57bc04e7007..bfe1457aa52 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -747,6 +747,15 @@
pre_noise = TRUE
post_noise = FALSE
+/obj/item/toy/crayon/spraycan/Initialize(mapload)
+ . = ..()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/improvised_coolant)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/toy/crayon/spraycan/isValidSurface(surface)
return (isfloorturf(surface) || iswallturf(surface))
diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm
index a8fa34ed5f8..0ab7e5d94b5 100644
--- a/code/game/objects/items/devices/aicard.dm
+++ b/code/game/objects/items/devices/aicard.dm
@@ -18,102 +18,6 @@
. = ..()
ADD_TRAIT(src, TRAIT_CASTABLE_LOC, INNATE_TRAIT)
-/obj/item/computer_disk/syndie_ai_upgrade
- name = "AI interaction range upgrade"
- desc = "A NT data chip containing information that a syndiCard AI can utilize to improve its wireless interfacing abilities. Simply slap it on top of an intelliCard, MODsuit, or AI core and watch it do its work! It's rumoured that there's something 'pretty awful' in it."
- icon = 'icons/obj/antags/syndicate_tools.dmi'
- icon_state = "something_awful"
- max_capacity = 1000
- w_class = WEIGHT_CLASS_NORMAL
-
-/obj/item/computer_disk/syndie_ai_upgrade/pre_attack(atom/A, mob/living/user, params)
- var/mob/living/silicon/ai/AI
- if(isAI(A))
- AI = A
- else
- AI = locate() in A
- if(!AI || AI.interaction_range == INFINITY)
- playsound(src,'sound/machines/buzz-sigh.ogg',50,FALSE)
- to_chat(user, span_notice("Error! Incompatible object!"))
- return ..()
- AI.interaction_range += 2
- if(AI.interaction_range > 7)
- AI.interaction_range = INFINITY
- playsound(src,'sound/machines/twobeep.ogg',50,FALSE)
- to_chat(user, span_notice("You insert [src] into [AI]'s compartment, and it beeps as it processes the data."))
- to_chat(AI, span_notice("You process [src], and find yourself able to manipulate electronics from up to [AI.interaction_range] meters!"))
- qdel(src)
-
-/obj/item/aicard/syndie
- name = "syndiCard"
- desc = "A storage device for AIs. Nanotrasen forgot to make the patent, so the Syndicate made their own version!"
- icon = 'icons/obj/aicards.dmi'
- icon_state = "syndicard"
- base_icon_state = "syndicard"
- item_flags = null
- force = 7
-
-/obj/item/aicard/syndie/loaded
- /// Set to true while we're waiting for ghosts to sign up
- var/finding_candidate = FALSE
-
-/obj/item/aicard/syndie/loaded/examine(mob/user)
- . = ..()
-
- . += span_notice("This one has a little S.E.L.F. insignia on the back, and a label next to it that says 'Activate for one FREE aligned AI! Please attempt uplink reintegration or ask your employers for reimbursal if AI is unavailable or belligerent.")
-
-/obj/item/aicard/syndie/loaded/attack_self(mob/user, modifiers)
- if(!isnull(AI))
- return ..()
- if(finding_candidate)
- balloon_alert(user, "loading...")
- return TRUE
- finding_candidate = TRUE
- to_chat(user, span_notice("Connecting to S.E.L.F. dispatch..."))
- procure_ai(user)
- finding_candidate = FALSE
- return TRUE
-
-/obj/item/aicard/syndie/loaded/proc/procure_ai(mob/user)
- var/datum/antagonist/nukeop/op_datum = user.mind?.has_antag_datum(/datum/antagonist/nukeop,TRUE)
- if(isnull(op_datum))
- balloon_alert(user, "invalid access!")
- return
- var/list/nuke_candidates = poll_ghost_candidates(
- question = "Do you want to play as a nuclear operative MODsuit AI?",
- jobban_type = ROLE_OPERATIVE,
- be_special_flag = ROLE_OPERATIVE_MIDROUND,
- poll_time = 15 SECONDS,
- ignore_category = POLL_IGNORE_SYNDICATE,
- )
- if(QDELETED(src))
- return
- if(!LAZYLEN(nuke_candidates))
- to_chat(user, span_warning("Unable to connect to S.E.L.F. dispatch. Please wait and try again later or use the intelliCard on your uplink to get your points refunded."))
- return
- // pick ghost, create AI and transfer
- var/mob/dead/observer/ghos = pick(nuke_candidates)
- var/mob/living/silicon/ai/weak_syndie/new_ai = new /mob/living/silicon/ai/weak_syndie(get_turf(src), new /datum/ai_laws/syndicate_override, ghos)
- // create and apply syndie datum
- var/datum/antagonist/nukeop/nuke_datum = new()
- nuke_datum.send_to_spawnpoint = FALSE
- new_ai.mind.add_antag_datum(nuke_datum, op_datum.nuke_team)
- new_ai.mind.special_role = "Syndicate AI"
- new_ai.faction |= ROLE_SYNDICATE
- new_ai.grant_language(/datum/language/codespeak, source = LANGUAGE_MIND)
- // Make it look evil!!!
- new_ai.hologram_appearance = mutable_appearance('icons/mob/silicon/ai.dmi',"xeno_queen") //good enough
- new_ai.icon_state = resolve_ai_icon("hades")
- // Transfer the AI from the core we created into the card, then delete the core
- capture_ai(new_ai, user)
- var/obj/structure/ai_core/deactivated/detritus = locate() in get_turf(src)
- qdel(detritus)
- AI.control_disabled = FALSE
- AI.radio_enabled = TRUE
- do_sparks(4, TRUE, src)
- playsound(src, 'sound/machines/chime.ogg', 25, TRUE)
- return
-
/obj/item/aicard/Destroy(force)
if(AI)
AI.ghostize(can_reenter_corpse = FALSE)
diff --git a/code/game/objects/items/devices/aicard_evil.dm b/code/game/objects/items/devices/aicard_evil.dm
new file mode 100644
index 00000000000..1a5fce6897a
--- /dev/null
+++ b/code/game/objects/items/devices/aicard_evil.dm
@@ -0,0 +1,104 @@
+/// One use AI card which downloads a ghost as a syndicate AI to put in your MODsuit
+/obj/item/aicard/syndie
+ name = "syndiCard"
+ desc = "A storage device for AIs. Nanotrasen forgot to make the patent, so the Syndicate made their own version!"
+ icon = 'icons/obj/aicards.dmi'
+ icon_state = "syndicard"
+ base_icon_state = "syndicard"
+ item_flags = null
+ force = 7
+
+/obj/item/aicard/syndie/loaded
+ /// Set to true while we're waiting for ghosts to sign up
+ var/finding_candidate = FALSE
+
+/obj/item/aicard/syndie/loaded/examine(mob/user)
+ . = ..()
+ . += span_notice("This one has a little S.E.L.F. insignia on the back, and a label next to it that says 'Activate for one FREE aligned AI! Please attempt uplink reintegration or ask your employers for reimbursal if AI is unavailable or belligerent.")
+
+/obj/item/aicard/syndie/loaded/attack_self(mob/user, modifiers)
+ if(!isnull(AI))
+ return ..()
+ if(finding_candidate)
+ balloon_alert(user, "loading...")
+ return TRUE
+ finding_candidate = TRUE
+ to_chat(user, span_notice("Connecting to S.E.L.F. dispatch..."))
+ procure_ai(user)
+ finding_candidate = FALSE
+ return TRUE
+
+/obj/item/aicard/syndie/loaded/proc/procure_ai(mob/user)
+ var/datum/antagonist/nukeop/op_datum = user.mind?.has_antag_datum(/datum/antagonist/nukeop,TRUE)
+ if(isnull(op_datum))
+ balloon_alert(user, "invalid access!")
+ return
+ var/list/nuke_candidates = poll_ghost_candidates(
+ question = "Do you want to play as a nuclear operative MODsuit AI?",
+ jobban_type = ROLE_OPERATIVE,
+ be_special_flag = ROLE_OPERATIVE_MIDROUND,
+ poll_time = 15 SECONDS,
+ ignore_category = POLL_IGNORE_SYNDICATE,
+ )
+ if(QDELETED(src))
+ return
+ if(!LAZYLEN(nuke_candidates))
+ to_chat(user, span_warning("Unable to connect to S.E.L.F. dispatch. Please wait and try again later or use the intelliCard on your uplink to get your points refunded."))
+ return
+ // pick ghost, create AI and transfer
+ var/mob/dead/observer/ghos = pick(nuke_candidates)
+ var/mob/living/silicon/ai/weak_syndie/new_ai = new /mob/living/silicon/ai/weak_syndie(get_turf(src), new /datum/ai_laws/syndicate_override, ghos)
+ // create and apply syndie datum
+ var/datum/antagonist/nukeop/nuke_datum = new()
+ nuke_datum.send_to_spawnpoint = FALSE
+ new_ai.mind.add_antag_datum(nuke_datum, op_datum.nuke_team)
+ new_ai.mind.special_role = "Syndicate AI"
+ new_ai.faction |= ROLE_SYNDICATE
+ // Make it look evil!!!
+ new_ai.hologram_appearance = mutable_appearance('icons/mob/silicon/ai.dmi',"xeno_queen") //good enough
+ new_ai.icon_state = resolve_ai_icon("hades")
+ // Transfer the AI from the core we created into the card, then delete the core
+ capture_ai(new_ai, user)
+ var/obj/structure/ai_core/deactivated/detritus = locate() in get_turf(src)
+ qdel(detritus)
+ AI.control_disabled = FALSE
+ AI.radio_enabled = TRUE
+ do_sparks(4, TRUE, src)
+ playsound(src, 'sound/machines/chime.ogg', 25, TRUE)
+ return
+
+/obj/item/aicard/syndie/loaded/upload_ai(atom/to_what, mob/living/user)
+ . = ..()
+ if (!.)
+ return
+ visible_message(span_warning("The expended card incinerates itself."))
+ do_sparks(3, cardinal_only = FALSE, source = src)
+ new /obj/effect/decal/cleanable/ash(get_turf(src))
+ qdel(src)
+
+/// Upgrade disk used to increase the range of a syndicate AI
+/obj/item/computer_disk/syndie_ai_upgrade
+ name = "AI interaction range upgrade"
+ desc = "A NT data chip containing information that a syndiCard AI can utilize to improve its wireless interfacing abilities. Simply slap it on top of an intelliCard, MODsuit, or AI core and watch it do its work! It's rumoured that there's something 'pretty awful' in it."
+ icon = 'icons/obj/antags/syndicate_tools.dmi'
+ icon_state = "something_awful"
+ max_capacity = 1000
+ w_class = WEIGHT_CLASS_NORMAL
+
+/obj/item/computer_disk/syndie_ai_upgrade/pre_attack(atom/A, mob/living/user, params)
+ var/mob/living/silicon/ai/AI
+ if(isAI(A))
+ AI = A
+ else
+ AI = locate() in A
+ if(!AI || AI.interaction_range == INFINITY)
+ playsound(src,'sound/machines/buzz-sigh.ogg',50,FALSE)
+ to_chat(user, span_notice("Error! Incompatible object!"))
+ return ..()
+ AI.interaction_range += 2
+ if(AI.interaction_range > 7)
+ AI.interaction_range = INFINITY
+ playsound(src,'sound/machines/twobeep.ogg',50,FALSE)
+ to_chat(user, span_notice("You insert [src] into [AI]'s compartment, and it beeps as it processes the data."))
+ to_chat(AI, span_notice("You process [src], and find yourself able to manipulate electronics from up to [AI.interaction_range] meters!"))
+ qdel(src)
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index ecf94d58f70..d3d280cd743 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -44,6 +44,13 @@
if(toggle_context)
RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur))
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/flashlight_eyes)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/flashlight/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
// single use lights can be toggled on once
if(isnull(held_item) && (toggle_context || !on))
diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm
index 17f5e7d4902..08dee828011 100644
--- a/code/game/objects/items/devices/multitool.dm
+++ b/code/game/objects/items/devices/multitool.dm
@@ -127,12 +127,6 @@
if(distance < rangewarning) //ai cant see us but is close
detect_state = PROXIMITY_NEAR
-/mob/camera/ai_eye/remote/ai_detector
- name = "AI detector eye"
- ai_detector_visible = FALSE
- visible_icon = FALSE
- use_static = FALSE
-
/datum/action/item_action/toggle_multitool
name = "Toggle AI detecting mode"
check_flags = NONE
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 1065d16d1ca..edd058bedd2 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -112,6 +112,13 @@
AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES)
+ // No subtypes
+ if(type != /obj/item/radio)
+ return
+ AddComponent(/datum/component/slapcrafting,\
+ slapcraft_recipes = list(/datum/crafting_recipe/improv_explosive)\
+ )
+
/obj/item/radio/Destroy()
remove_radio_all(src) //Just to be sure
QDEL_NULL(wires)
diff --git a/code/game/objects/items/devices/scanners/gas_analyzer.dm b/code/game/objects/items/devices/scanners/gas_analyzer.dm
index 727d38c245c..36819d8502a 100644
--- a/code/game/objects/items/devices/scanners/gas_analyzer.dm
+++ b/code/game/objects/items/devices/scanners/gas_analyzer.dm
@@ -26,6 +26,15 @@
. = ..()
RegisterSignal(src, COMSIG_TOOL_ATOM_ACTED_PRIMARY(tool_behaviour), PROC_REF(on_analyze))
+ if(type != /obj/item/analyzer)
+ return
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/material_sniffer)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/analyzer/equipped(mob/user, slot, initial)
. = ..()
ADD_TRAIT(user, TRAIT_DETECT_STORM, CLOTHING_TRAIT)
diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm
index 69193b7df92..8947e83d363 100644
--- a/code/game/objects/items/extinguisher.dm
+++ b/code/game/objects/items/extinguisher.dm
@@ -43,6 +43,15 @@
/// Icon state when inside a tank holder.
var/tank_holder_icon_state = "holder_extinguisher"
+/obj/item/extinguisher/Initialize(mapload)
+ . = ..()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/ghettojetpack)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/extinguisher/empty
starting_water = FALSE
diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm
index 035af619513..eb94626c86e 100644
--- a/code/game/objects/items/flamethrower.dm
+++ b/code/game/objects/items/flamethrower.dm
@@ -34,6 +34,12 @@
/obj/item/flamethrower/Initialize(mapload)
. = ..()
AddElement(/datum/element/update_icon_updates_onmob)
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/flamethrower)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
/obj/item/flamethrower/Destroy()
if(weldtool)
diff --git a/code/game/objects/items/food/burgers.dm b/code/game/objects/items/food/burgers.dm
index 191cc0eaf25..b2d779ca3a5 100644
--- a/code/game/objects/items/food/burgers.dm
+++ b/code/game/objects/items/food/burgers.dm
@@ -688,3 +688,4 @@
tastes = list("juicy meat" = 4, "BBQ sauce" = 3, "onions" = 2, "bun" = 2)
foodtypes = GRAIN | MEAT | VEGETABLES
venue_value = FOOD_PRICE_NORMAL
+ crafting_complexity = FOOD_COMPLEXITY_3
diff --git a/code/game/objects/items/food/cake.dm b/code/game/objects/items/food/cake.dm
index 5d33c332ff6..07d5818b466 100644
--- a/code/game/objects/items/food/cake.dm
+++ b/code/game/objects/items/food/cake.dm
@@ -690,6 +690,7 @@
tastes = list("cake" = 2, "cream" = 3, "pineapple" = 4)
foodtypes = GRAIN | DAIRY | SUGAR | FRUIT | PINEAPPLE
slice_type = /obj/item/food/cakeslice/pineapple_cream_cake
+ crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/cakeslice/pineapple_cream_cake
name = "pineapple cream cake slice"
@@ -702,3 +703,4 @@
)
tastes = list("cake" = 2, "cream" = 3, "pineapple" = 4)
foodtypes = GRAIN | DAIRY | SUGAR | FRUIT | PINEAPPLE
+ crafting_complexity = FOOD_COMPLEXITY_3
diff --git a/code/game/objects/items/food/meatdish.dm b/code/game/objects/items/food/meatdish.dm
index 07cd70ea013..2d376148045 100644
--- a/code/game/objects/items/food/meatdish.dm
+++ b/code/game/objects/items/food/meatdish.dm
@@ -1017,6 +1017,7 @@
)
tastes = list("meat" = 5, "savory sauce" = 4, "tangy pineapple" = 3, "pepper" = 2)
foodtypes = MEAT | VEGETABLES | FRUIT | PINEAPPLE
+ crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/kebab/pineapple_skewer
name = "pineapple skewer"
@@ -1029,6 +1030,7 @@
)
tastes = list("juicy meat" = 4, "pineapple" = 3)
foodtypes = MEAT | FRUIT | PINEAPPLE
+ crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/futomaki_sushi_roll
name = "futomaki sushi roll"
@@ -1042,6 +1044,7 @@
tastes = list("boiled rice" = 4, "fish" = 5, "egg" = 3, "dried seaweed" = 2, "cucumber" = 2)
foodtypes = VEGETABLES | SEAFOOD
w_class = WEIGHT_CLASS_SMALL
+ crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/futomaki_sushi_roll/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/futomaki_sushi_slice, 4, screentip_verb = "Chop")
@@ -1058,6 +1061,7 @@
tastes = list("boiled rice" = 4, "fish" = 5, "egg" = 3, "dried seaweed" = 2, "cucumber" = 2)
foodtypes = VEGETABLES | SEAFOOD
w_class = WEIGHT_CLASS_SMALL
+ crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/philadelphia_sushi_roll
name = "Philadelphia sushi roll"
@@ -1071,6 +1075,7 @@
tastes = list("boiled rice" = 4, "fish" = 5, "creamy cheese" = 3, "dried seaweed" = 2, "cucumber" = 2)
foodtypes = VEGETABLES | SEAFOOD | DAIRY
w_class = WEIGHT_CLASS_SMALL
+ crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/philadelphia_sushi_roll/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/philadelphia_sushi_slice, 4, screentip_verb = "Chop")
@@ -1087,3 +1092,4 @@
tastes = list("boiled rice" = 4, "fish" = 5, "creamy cheese" = 3, "dried seaweed" = 2, "cucumber" = 2)
foodtypes = VEGETABLES | SEAFOOD | DAIRY
w_class = WEIGHT_CLASS_SMALL
+ crafting_complexity = FOOD_COMPLEXITY_3
diff --git a/code/game/objects/items/food/mexican.dm b/code/game/objects/items/food/mexican.dm
index 58c50ba5863..b4e32587bc6 100644
--- a/code/game/objects/items/food/mexican.dm
+++ b/code/game/objects/items/food/mexican.dm
@@ -336,3 +336,4 @@
tastes = list("pineapple" = 4, "tomato" = 3, "onion" = 2, "chili" = 2)
foodtypes = VEGETABLES | FRUIT | PINEAPPLE
w_class = WEIGHT_CLASS_SMALL
+ crafting_complexity = FOOD_COMPLEXITY_3
diff --git a/code/game/objects/items/food/misc.dm b/code/game/objects/items/food/misc.dm
index 67e74496260..ba72e93a8b0 100644
--- a/code/game/objects/items/food/misc.dm
+++ b/code/game/objects/items/food/misc.dm
@@ -550,6 +550,7 @@
tastes = list("cooked eggplant" = 5, "cheese" = 4, "ground meat" = 3, "veggies" = 2)
foodtypes = VEGETABLES | MEAT | DAIRY
w_class = WEIGHT_CLASS_SMALL
+ crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/moussaka
name = "moussaka"
@@ -562,6 +563,7 @@
)
tastes = list("cooked eggplant" = 5, "potato" = 1, "baked veggies" = 2, "meat" = 4, "bechamel sauce" = 3)
foodtypes = MEAT | DAIRY | VEGETABLES
+ crafting_complexity = FOOD_COMPLEXITY_4
/obj/item/food/moussaka/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/moussaka_slice, 4, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
@@ -577,6 +579,7 @@
)
tastes = list("cooked eggplant" = 5, "potato" = 1, "baked veggies" = 2, "meat" = 4, "bechamel sauce" = 3)
foodtypes = MEAT | DAIRY | VEGETABLES
+ crafting_complexity = FOOD_COMPLEXITY_4
/obj/item/food/candied_pineapple
name = "candied pineapple"
@@ -591,6 +594,7 @@
foodtypes = FRUIT | SUGAR
food_flags = FOOD_FINGER_FOOD
w_class = WEIGHT_CLASS_TINY
+ crafting_complexity = FOOD_COMPLEXITY_1
/obj/item/food/candied_pineapple/Initialize(mapload)
. = ..()
@@ -608,6 +612,7 @@
tastes = list("dough" = 2)
foodtypes = GRAIN
w_class = WEIGHT_CLASS_TINY
+ crafting_complexity = FOOD_COMPLEXITY_1
/obj/item/food/raw_pita_bread/make_grillable()
AddComponent(/datum/component/grillable, /obj/item/food/pita_bread, rand(15 SECONDS, 30 SECONDS), TRUE, TRUE)
@@ -627,6 +632,7 @@
tastes = list("pita bread" = 2)
foodtypes = GRAIN
w_class = WEIGHT_CLASS_TINY
+ crafting_complexity = FOOD_COMPLEXITY_2
/obj/item/food/tzatziki_sauce
name = "tzatziki sauce"
@@ -639,6 +645,7 @@
tastes = list("garlic" = 4, "cucumber" = 2, "olive oil" = 2)
foodtypes = VEGETABLES
w_class = WEIGHT_CLASS_TINY
+ crafting_complexity = FOOD_COMPLEXITY_2
/obj/item/food/tzatziki_and_pita_bread
name = "tzatziki and pita bread"
@@ -651,6 +658,7 @@
tastes = list("pita bread" = 4, "tzatziki sauce" = 2, "olive oil" = 2)
foodtypes = VEGETABLES | GRAIN
w_class = WEIGHT_CLASS_TINY
+ crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/grilled_beef_gyro
name = "grilled beef gyro"
@@ -664,6 +672,7 @@
tastes = list("pita bread" = 4, "tender meat" = 2, "tzatziki sauce" = 2, "mixed veggies" = 2)
foodtypes = VEGETABLES | GRAIN | MEAT
w_class = WEIGHT_CLASS_TINY
+ crafting_complexity = FOOD_COMPLEXITY_4
/obj/item/food/vegetarian_gyro
name = "vegetarian gyro"
@@ -676,3 +685,4 @@
tastes = list("pita bread" = 4, "cucumber" = 2, "tzatziki sauce" = 2, "mixed veggies" = 2)
foodtypes = VEGETABLES | GRAIN
w_class = WEIGHT_CLASS_TINY
+ crafting_complexity = FOOD_COMPLEXITY_4
diff --git a/code/game/objects/items/food/pastries.dm b/code/game/objects/items/food/pastries.dm
index 46da05dea14..8a39f6df8d1 100644
--- a/code/game/objects/items/food/pastries.dm
+++ b/code/game/objects/items/food/pastries.dm
@@ -540,6 +540,7 @@
foodtypes = GRAIN | SUGAR | DAIRY
food_flags = FOOD_FINGER_FOOD
w_class = WEIGHT_CLASS_SMALL
+ crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/cookie/snickerdoodle
name = "snickerdoodle"
@@ -550,6 +551,7 @@
foodtypes = GRAIN | SUGAR | DAIRY
food_flags = FOOD_FINGER_FOOD
w_class = WEIGHT_CLASS_SMALL
+ crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/cookie/macaron
name = "macaron"
@@ -561,6 +563,7 @@
foodtypes = GRAIN | SUGAR | DAIRY
food_flags = FOOD_FINGER_FOOD
w_class = WEIGHT_CLASS_TINY
+ crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/cookie/macaron/Initialize(mapload)
. = ..()
@@ -575,3 +578,4 @@
foodtypes = GRAIN | SUGAR | FRUIT
food_flags = FOOD_FINGER_FOOD
w_class = WEIGHT_CLASS_SMALL
+ crafting_complexity = FOOD_COMPLEXITY_3
diff --git a/code/game/objects/items/food/sandwichtoast.dm b/code/game/objects/items/food/sandwichtoast.dm
index 8d6e8c8d147..fec714ad850 100644
--- a/code/game/objects/items/food/sandwichtoast.dm
+++ b/code/game/objects/items/food/sandwichtoast.dm
@@ -259,23 +259,45 @@
. = ..()
obj_flags &= ~UNIQUE_RENAME // You shouldn't be able to disguise this on account of how it kills you
-///Override for checkliked callback
+// Makes you feel disgusted if you look at it wrong.
+/obj/item/food/sandwich/death/examine(mob/user)
+ . = ..()
+ // Only human mobs, not animals or silicons, can like/dislike by this.
+ if(!ishuman(user))
+ return
+ if(check_liked(user) == FOOD_LIKED)
+ return
+ to_chat(user, span_warning("You imagine yourself eating [src]. You feel a sudden sour taste in your mouth, and a horrible feeling that you've done something wrong."))
+ user.adjust_disgust(33)
+
+// Override for after_eat and check_liked callbacks.
/obj/item/food/sandwich/death/make_edible()
. = ..()
- AddComponent(/datum/component/edible, check_liked = CALLBACK(src, PROC_REF(check_liked)))
+ AddComponent(/datum/component/edible, after_eat = CALLBACK(src, PROC_REF(after_eat)), check_liked = CALLBACK(src, PROC_REF(check_liked)))
/**
* Callback to be used with the edible component.
-* If you eat the sandwich with the right clothes and hairstyle, you like it.
-* If you don't, you contract a deadly disease.
+* If you have the right clothes and hairstyle, you like it.
+* If you don't, you don't like it.
*/
/obj/item/food/sandwich/death/proc/check_liked(mob/living/carbon/human/consumer)
- /// Closest thing to a mullet we have
+ // Closest thing to a mullet we have
if(consumer.hairstyle == "Gelled Back" && istype(consumer.get_item_by_slot(ITEM_SLOT_ICLOTHING), /obj/item/clothing/under/rank/civilian/cookjorts))
return FOOD_LIKED
+ return FOOD_DISLIKED
+
+/**
+* Callback to be used with the edible component.
+* If you take a bite of the sandwich with the right clothes and hairstyle, you like it.
+* If you don't, you contract a deadly disease.
+*/
+/obj/item/food/sandwich/death/proc/after_eat(mob/living/carbon/human/consumer)
+ // If you like it, you're eating it right.
+ if(check_liked(consumer) == FOOD_LIKED)
+ return
// I thought it didn't make sense for it to instantly kill you, so instead enjoy shitloads of toxin damage per bite.
balloon_alert(consumer, "ate it wrong!")
- consumer.ForceContractDisease(new/datum/disease/death_sandwich_poisoning())
+ consumer.ForceContractDisease(new /datum/disease/death_sandwich_poisoning())
/obj/item/food/sandwich/death/suicide_act(mob/living/user)
user.visible_message(span_suicide("[user] starts to shove [src] down [user.p_their()] throat the wrong way. It looks like [user.p_theyre()] trying to commit suicide!"))
diff --git a/code/game/objects/items/food/spaghetti.dm b/code/game/objects/items/food/spaghetti.dm
index a631cfe5e05..cab4a62a29f 100644
--- a/code/game/objects/items/food/spaghetti.dm
+++ b/code/game/objects/items/food/spaghetti.dm
@@ -178,6 +178,7 @@
)
tastes = list("noodles" = 5, "meat" = 3, "egg" = 4, "dried seaweed" = 2)
foodtypes = GRAIN | MEAT | VEGETABLES
+ crafting_complexity = FOOD_COMPLEXITY_4
/obj/item/food/spaghetti/kitakata_ramen
name = "kitakata ramen"
@@ -191,6 +192,7 @@
)
tastes = list("noodles" = 5, "meat" = 4, "mushrooms" = 3, "onion" = 2)
foodtypes = GRAIN | MEAT | VEGETABLES
+ crafting_complexity = FOOD_COMPLEXITY_4
/obj/item/food/spaghetti/kitsune_udon
name = "kitsune udon"
@@ -204,6 +206,7 @@
)
tastes = list("noodles" = 5, "tofu" = 4, "sugar" = 3, "soy sauce" = 2)
foodtypes = GRAIN | VEGETABLES
+ crafting_complexity = FOOD_COMPLEXITY_4
/obj/item/food/spaghetti/nikujaga
name = "nikujaga"
@@ -217,6 +220,7 @@
)
tastes = list("noodles" = 5, "meat" = 4, "potato" = 3, "onion" = 2, "mixed veggies" = 2)
foodtypes = GRAIN | VEGETABLES | MEAT
+ crafting_complexity = FOOD_COMPLEXITY_4
/obj/item/food/spaghetti/pho
name = "pho"
@@ -230,6 +234,7 @@
)
tastes = list("noodles" = 5, "meat" = 4, "cabbage" = 3, "onion" = 2, "herbs" = 2)
foodtypes = GRAIN | VEGETABLES | MEAT
+ crafting_complexity = FOOD_COMPLEXITY_4
/obj/item/food/spaghetti/pad_thai
name = "pad thai"
@@ -243,3 +248,4 @@
)
tastes = list("noodles" = 5, "fried tofu" = 4, "lime" = 2, "peanut" = 3, "onion" = 2)
foodtypes = GRAIN | VEGETABLES | NUTS | FRUIT
+ crafting_complexity = FOOD_COMPLEXITY_4
diff --git a/code/game/objects/items/food/vegetables.dm b/code/game/objects/items/food/vegetables.dm
index 7da97abc484..dd3ae8c450b 100644
--- a/code/game/objects/items/food/vegetables.dm
+++ b/code/game/objects/items/food/vegetables.dm
@@ -175,6 +175,7 @@
tastes = list("fried eggplant" = 4, "garlic" = 2, "olive oil" = 3)
foodtypes = VEGETABLES
w_class = WEIGHT_CLASS_SMALL
+ crafting_complexity = FOOD_COMPLEXITY_2
/obj/item/food/baba_ghanoush
name = "baba ghanoush"
@@ -188,6 +189,7 @@
tastes = list("mashed eggplant" = 5, "pita bread" = 4, "garlic" = 3, "olive oil" = 4, "lemon juice" = 2)
foodtypes = VEGETABLES | GRAIN
w_class = WEIGHT_CLASS_SMALL
+ crafting_complexity = FOOD_COMPLEXITY_2
/obj/item/food/falafel
name = "falafel"
@@ -200,3 +202,4 @@
tastes = list("fava beans" = 5, "garlic" = 3, "onion" = 2, "fresh herbs" = 4)
foodtypes = VEGETABLES
w_class = WEIGHT_CLASS_SMALL
+ crafting_complexity = FOOD_COMPLEXITY_3
diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm
index df18b540453..daee6043682 100644
--- a/code/game/objects/items/handcuffs.dm
+++ b/code/game/objects/items/handcuffs.dm
@@ -175,10 +175,6 @@
. = ..()
var/static/list/hovering_item_typechecks = list(
- /obj/item/stack/rods = list(
- SCREENTIP_CONTEXT_LMB = "Craft wired rod",
- ),
-
/obj/item/stack/sheet/iron = list(
SCREENTIP_CONTEXT_LMB = "Craft bola",
),
@@ -190,6 +186,13 @@
if(new_color)
set_cable_color(new_color)
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/bola, /datum/crafting_recipe/gonbola)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/restraints/handcuffs/cable/proc/set_cable_color(new_color)
color = GLOB.cable_colors[new_color]
cable_color = new_color
@@ -289,36 +292,6 @@
cable_color = CABLE_COLOR_WHITE
inhand_icon_state = "coil_white"
-/obj/item/restraints/handcuffs/cable/attackby(obj/item/I, mob/user, params) //Slapcrafting
- if(istype(I, /obj/item/stack/rods))
- var/obj/item/stack/rods/R = I
- if (R.use(1))
- var/obj/item/wirerod/W = new /obj/item/wirerod
- remove_item_from_storage(user)
- user.put_in_hands(W)
- to_chat(user, span_notice("You wrap [src] around the top of [I]."))
- qdel(src)
- else
- to_chat(user, span_warning("You need one rod to make a wired rod!"))
- return
- else if(istype(I, /obj/item/stack/sheet/iron))
- var/obj/item/stack/sheet/iron/M = I
- if(M.get_amount() < 6)
- to_chat(user, span_warning("You need at least six iron sheets to make good enough weights!"))
- return
- to_chat(user, span_notice("You begin to apply [I] to [src]..."))
- if(do_after(user, 35, target = src))
- if(M.get_amount() < 6 || !M)
- return
- var/obj/item/restraints/legcuffs/bola/S = new /obj/item/restraints/legcuffs/bola
- M.use(6)
- user.put_in_hands(S)
- to_chat(user, span_notice("You make some weights out of [I] and tie them to [src]."))
- remove_item_from_storage(user)
- qdel(src)
- else
- return ..()
-
/**
* # Zipties
*
diff --git a/code/game/objects/items/implants/implant_freedom.dm b/code/game/objects/items/implants/implant_freedom.dm
index d010b57e506..1fa61c27510 100644
--- a/code/game/objects/items/implants/implant_freedom.dm
+++ b/code/game/objects/items/implants/implant_freedom.dm
@@ -3,37 +3,45 @@
desc = "Use this to escape from those evil Red Shirts."
icon_state = "freedom"
implant_color = "r"
- uses = 4
+ uses = FREEDOM_IMPLANT_CHARGES
+/obj/item/implant/freedom/implant(mob/living/target, mob/user, silent, force)
+ . = ..()
+ if(!.)
+ return FALSE
+ if(!iscarbon(target)) //This is pretty much useless for anyone else since they can't be cuffed
+ balloon_alert(user, "that would be a waste!")
+ return FALSE
+ return TRUE
/obj/item/implant/freedom/activate()
. = ..()
+ var/mob/living/carbon/carbon_imp_in = imp_in
+ if(!carbon_imp_in.handcuffed && !carbon_imp_in.legcuffed)
+ balloon_alert(carbon_imp_in, "no restraints!")
+ return
+
uses--
- to_chat(imp_in, span_hear("You feel a faint click."))
- if(iscarbon(imp_in))
- var/mob/living/carbon/C_imp_in = imp_in
- C_imp_in.uncuff()
+
+ carbon_imp_in.uncuff()
if(!uses)
+ addtimer(CALLBACK(carbon_imp_in, TYPE_PROC_REF(/atom, balloon_alert), carbon_imp_in, "implant degraded!"), 1 SECONDS)
qdel(src)
-
/obj/item/implant/freedom/get_data()
var/dat = {"
-Implant Specifications:
-Name: Freedom Beacon
-Life: optimum 5 uses
-Important Notes: Illegal
-
-Implant Details:
-Function: Transmits a specialized cluster of signals to override handcuff locking
-mechanisms
-Special Features:
-Neuro-Scan- Analyzes certain shadow signals in the nervous system
-
-No Implant Specifics"}
+ Implant Specifications:
+ Name: Freedom Beacon
+ Life: Optimum [initial(uses)] uses
+ Important Notes: Illegal
+
+ Implant Details:
+ Function: Transmits a specialized cluster of signals to override handcuff locking
+ mechanisms. These signals will release any bindings on both the arms and legs.
+ Disclaimer: Heavy-duty restraints such as straightjackets are deemed "too complex" to release from.
+ "}
return dat
-
/obj/item/implanter/freedom
name = "implanter" // Skyrat edit , was implanter (freedom)
imp_type = /obj/item/implant/freedom
diff --git a/code/game/objects/items/mail.dm b/code/game/objects/items/mail.dm
index b377fdde172..d058f96a40c 100644
--- a/code/game/objects/items/mail.dm
+++ b/code/game/objects/items/mail.dm
@@ -452,9 +452,10 @@
var/list/mail_recipients_for_input = list("Anyone")
var/list/used_names = list()
for(var/datum/record/locked/person in sort_record(GLOB.manifest.locked))
- if(isnull(person.mind_ref))
+ var/datum/mind/locked_mind = person.mind_ref.resolve()
+ if(isnull(locked_mind))
continue
- mail_recipients += person.mind_ref
+ mail_recipients += locked_mind
mail_recipients_for_input += avoid_assoc_duplicate_keys(person.name, used_names)
var/recipient = tgui_input_list(user, "Choose a recipient", "Mail Counterfeiting", mail_recipients_for_input)
diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm
index d41397301b3..27418a5e0a9 100644
--- a/code/game/objects/items/shields.dm
+++ b/code/game/objects/items/shields.dm
@@ -111,6 +111,15 @@
shield_break_sound = 'sound/effects/glassbr3.ogg'
shield_break_leftover = /obj/item/shard
+/obj/item/shield/riot/Initialize(mapload)
+ . = ..()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/strobeshield)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/shield/riot/attackby(obj/item/attackby_item, mob/user, params)
if(istype(attackby_item, /obj/item/melee/baton))
if(!COOLDOWN_FINISHED(src, baton_bash))
diff --git a/code/game/objects/items/spear.dm b/code/game/objects/items/spear.dm
index 1d9c90217ac..d9f13911731 100644
--- a/code/game/objects/items/spear.dm
+++ b/code/game/objects/items/spear.dm
@@ -54,8 +54,18 @@
force_wielded = force_wielded, \
icon_wielded = "[icon_prefix]1", \
)
+ add_headpike_component()
update_appearance()
+// I dunno man
+/obj/item/spear/proc/add_headpike_component()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/headpike)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/spear/update_icon_state()
icon_state = "[icon_prefix]0"
return ..()
@@ -227,6 +237,14 @@
reach = 2
//SKYRAT EDIT ADDITION END
+/obj/item/spear/bonespear/add_headpike_component()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/headpikebone)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/*
* Bamboo Spear
*/
@@ -241,3 +259,12 @@
custom_materials = list(/datum/material/bamboo = SHEET_MATERIAL_AMOUNT * 20)
force_unwielded = 10
force_wielded = 18
+
+
+/obj/item/spear/bamboospear/add_headpike_component()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/headpikebamboo)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm
index 60db8f800a2..b5540a633f1 100644
--- a/code/game/objects/items/stacks/rods.dm
+++ b/code/game/objects/items/stacks/rods.dm
@@ -55,6 +55,13 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \
)
AddElement(/datum/element/contextual_screentip_tools, tool_behaviors)
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/spear, /datum/crafting_recipe/stunprod, /datum/crafting_recipe/teleprod) // snatcher prod isn't here as a spoopy secret
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/stack/rods/handle_openspace_click(turf/target, mob/user, proximity_flag, click_parameters)
if(proximity_flag)
target.attackby(src, user, click_parameters)
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index 289920c8889..381cdd7a296 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -501,6 +501,15 @@ GLOBAL_LIST_INIT(durathread_recipes, list ( \
drop_sound = 'sound/items/handling/cloth_drop.ogg'
pickup_sound = 'sound/items/handling/cloth_pickup.ogg'
+/obj/item/stack/sheet/durathread/Initialize(mapload)
+ . = ..()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/durathread_helmet, /datum/crafting_recipe/durathread_vest)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/stack/sheet/durathread/get_main_recipes()
. = ..()
. += GLOB.durathread_recipes
@@ -620,6 +629,15 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \
grind_results = list(/datum/reagent/cellulose = 10)
material_type = /datum/material/cardboard
+/obj/item/stack/sheet/cardboard/Initialize(mapload, new_amount, merge, list/mat_override, mat_amt)
+ . = ..()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/cardboard_id)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/stack/sheet/cardboard/get_main_recipes()
. = ..()
. += GLOB.cardboard_recipes
diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm
index c9c4815e3da..c0d2d42bb87 100644
--- a/code/game/objects/items/storage/backpack.dm
+++ b/code/game/objects/items/storage/backpack.dm
@@ -49,6 +49,12 @@
resistance_flags = FIRE_PROOF
item_flags = NO_MAT_REDEMPTION
+/obj/item/bag_of_holding_inert/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/slapcrafting,\
+ slapcraft_recipes = list(/datum/crafting_recipe/boh)\
+ )
+
/obj/item/storage/backpack/holding
name = "bag of holding"
desc = "A backpack that opens into a localized pocket of bluespace."
@@ -509,46 +515,12 @@
icon_state = "duffel-medical"
inhand_icon_state = "duffel-med"
-/obj/item/storage/backpack/duffelbag/med/surgery
- name = "surgical duffel bag"
- desc = "A large duffel bag for holding extra medical supplies - this one seems to be designed for holding surgical tools."
-
-/obj/item/storage/backpack/duffelbag/med/surgery/PopulateContents()
- new /obj/item/scalpel(src)
- new /obj/item/hemostat(src)
- new /obj/item/retractor(src)
- new /obj/item/circular_saw(src)
- new /obj/item/surgicaldrill(src)
- new /obj/item/cautery(src)
- new /obj/item/bonesetter(src)
- new /obj/item/surgical_drapes(src)
- new /obj/item/clothing/suit/toggle/labcoat/skyrat/hospitalgown(src) //SKYRAT EDIT ADDITION
- new /obj/item/clothing/mask/surgical(src)
- new /obj/item/razor(src)
- new /obj/item/blood_filter(src)
-
/obj/item/storage/backpack/duffelbag/coroner
name = "coroner duffel bag"
desc = "A large duffel bag for holding large amounts of organs at once."
icon_state = "duffel-coroner"
inhand_icon_state = "duffel-coroner"
-/obj/item/storage/backpack/duffelbag/coroner/surgery
- name = "surgical coroner bag"
- desc = "A large duffel bag for holding extra medical supplies - this one seems to be designed for holding morbid surgical tools."
-
-/obj/item/storage/backpack/duffelbag/coroner/surgery/PopulateContents()
- new /obj/item/scalpel/cruel(src)
- new /obj/item/hemostat/cruel(src)
- new /obj/item/retractor/cruel(src)
- new /obj/item/circular_saw(src)
- new /obj/item/surgicaldrill(src)
- new /obj/item/cautery/cruel(src)
- new /obj/item/bonesetter(src)
- new /obj/item/surgical_drapes(src)
- new /obj/item/razor(src)
- new /obj/item/blood_filter(src)
-
/obj/item/storage/backpack/duffelbag/explorer
name = "explorer duffel bag"
desc = "A large duffel bag for holding extra exotic treasures."
diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm
index ba9c6ef4812..9fa66404aed 100644
--- a/code/game/objects/items/storage/uplink_kits.dm
+++ b/code/game/objects/items/storage/uplink_kits.dm
@@ -747,13 +747,13 @@
human_target.reagents.add_reagent(/datum/reagent/toxin, 2)
return FALSE
- /// If no antag datums which allow induction are there, disallow induction! No self-antagging.
- var/allowed = FALSE
+ /// If all the antag datums are 'fake', disallow induction! No self-antagging.
+ var/faker
for(var/datum/antagonist/antag_datum as anything in human_target.mind.antag_datums)
- if((antag_datum.antag_flags & FLAG_ANTAG_CAN_BE_INDUCTED))
- allowed = TRUE
+ if((antag_datum.antag_flags & FLAG_FAKE_ANTAG))
+ faker = TRUE
- if(!allowed) // GTFO. Technically not foolproof but making a heartbreaker or a paradox clone a nuke op sounds hilarious
+ if(faker) // GTFO. Technically not foolproof but making a heartbreaker or a paradox clone a nuke op sounds hilarious
to_chat(human_target, span_notice("Huh? Nothing happened? But you're starting to feel a little ill..."))
human_target.reagents.add_reagent(/datum/reagent/toxin, 15)
return FALSE
diff --git a/code/game/objects/items/surgery_tray.dm b/code/game/objects/items/surgery_tray.dm
index dfe83baabdb..37494a39b55 100644
--- a/code/game/objects/items/surgery_tray.dm
+++ b/code/game/objects/items/surgery_tray.dm
@@ -11,6 +11,7 @@
/obj/item/cautery,
/obj/item/circular_saw,
/obj/item/clothing/mask/surgical,
+ /obj/item/clothing/suit/toggle/labcoat/skyrat/hospitalgown, // SKYRAT EDIT ADDITION
/obj/item/hemostat,
/obj/item/razor,
/obj/item/reagent_containers/medigel,
@@ -152,8 +153,10 @@
/obj/item/surgery_tray/attack_hand(mob/living/user)
if(!user.can_perform_action(src, NEED_HANDS))
return ..()
- var/obj/item/grabbies = pick(contents)
- if(grabbies)
+ if(!length(contents))
+ balloon_alert(user, "empty!")
+ else
+ var/obj/item/grabbies = pick(contents)
atom_storage.remove_single(user, grabbies, drop_location())
user.put_in_hands(grabbies)
return TRUE
@@ -193,6 +196,7 @@
new /obj/item/cautery(src)
new /obj/item/circular_saw(src)
new /obj/item/clothing/mask/surgical(src)
+ new /obj/item/clothing/suit/toggle/labcoat/skyrat/hospitalgown(src) // SKYRAT EDIT ADDITION
new /obj/item/hemostat(src)
new /obj/item/razor/surgery(src)
new /obj/item/retractor(src)
@@ -207,13 +211,14 @@
name = "autopsy tray"
desc = "A Deforest brand surgery tray, made for use in morgues. It is a folding model, \
meaning the wheels on the bottom can be extended outwards, making it a cart."
-
+
/obj/item/surgery_tray/full/morgue/populate_contents()
new /obj/item/blood_filter(src)
new /obj/item/bonesetter(src)
new /obj/item/cautery/cruel(src)
new /obj/item/circular_saw(src)
new /obj/item/clothing/mask/surgical(src)
+ new /obj/item/clothing/suit/toggle/labcoat/skyrat/hospitalgown(src) // SKYRAT EDIT ADDITION
new /obj/item/hemostat/cruel(src)
new /obj/item/razor/surgery(src)
new /obj/item/retractor/cruel(src)
@@ -227,13 +232,13 @@
/obj/item/surgery_tray/full/advanced
/obj/item/surgery_tray/full/advanced/populate_contents()
- new /obj/item/scalpel/advanced
- new /obj/item/retractor/advanced
- new /obj/item/cautery/advanced
- new /obj/item/surgical_drapes
- new /obj/item/reagent_containers/medigel/sterilizine
- new /obj/item/bonesetter
- new /obj/item/blood_filter
- new /obj/item/stack/medical/bone_gel
- new /obj/item/stack/sticky_tape/surgical
- new /obj/item/clothing/mask/surgical
+ new /obj/item/scalpel/advanced(src)
+ new /obj/item/retractor/advanced(src)
+ new /obj/item/cautery/advanced(src)
+ new /obj/item/surgical_drapes(src)
+ new /obj/item/reagent_containers/medigel/sterilizine(src)
+ new /obj/item/bonesetter(src)
+ new /obj/item/blood_filter(src)
+ new /obj/item/stack/medical/bone_gel(src)
+ new /obj/item/stack/sticky_tape/surgical(src)
+ new /obj/item/clothing/mask/surgical(src)
diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm
index 470448ab244..21fc15572bf 100644
--- a/code/game/objects/items/weaponry.dm
+++ b/code/game/objects/items/weaponry.dm
@@ -302,69 +302,6 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
/obj/item/katana/cursed //used by wizard events, see the tendril_loot.dm file for the miner one
slot_flags = null
-/obj/item/wirerod
- name = "wired rod"
- desc = "A rod with some wire wrapped around the top. It'd be easy to attach something to the top bit."
- icon = 'icons/obj/weapons/spear.dmi'
- icon_state = "wiredrod"
- inhand_icon_state = "rods"
- flags_1 = CONDUCT_1
- force = 9
- throwforce = 10
- w_class = WEIGHT_CLASS_BULKY
- custom_materials = list(/datum/material/iron= HALF_SHEET_MATERIAL_AMOUNT + SMALL_MATERIAL_AMOUNT * 1.5, /datum/material/glass= SMALL_MATERIAL_AMOUNT * 0.75)
- attack_verb_continuous = list("hits", "bludgeons", "whacks", "bonks")
- attack_verb_simple = list("hit", "bludgeon", "whack", "bonk")
-
-/obj/item/wirerod/Initialize(mapload)
- . = ..()
-
- var/static/list/hovering_item_typechecks = list(
- /obj/item/shard = list(
- SCREENTIP_CONTEXT_LMB = "Craft spear",
- ),
-
- /obj/item/assembly/igniter = list(
- SCREENTIP_CONTEXT_LMB = "Craft stunprod",
- ),
- )
-
- AddElement(/datum/element/contextual_screentip_item_typechecks, hovering_item_typechecks)
-
-/obj/item/wirerod/attackby(obj/item/attacking_item, mob/user, params)
- if(istype(attacking_item, /obj/item/shard))
- var/datum/crafting_recipe/recipe_to_use = /datum/crafting_recipe/spear
- user.balloon_alert(user, "crafting spear...")
- if(do_after(user, initial(recipe_to_use.time), src)) // we do initial work here to get the correct timer
- var/obj/item/spear/crafted_spear = new /obj/item/spear()
-
- remove_item_from_storage(user)
- if (!user.transferItemToLoc(attacking_item, crafted_spear))
- return
- crafted_spear.CheckParts(list(attacking_item))
- qdel(src)
-
- user.put_in_hands(crafted_spear)
- user.balloon_alert(user, "crafted spear")
- return
-
- if(isigniter(attacking_item) && !(HAS_TRAIT(attacking_item, TRAIT_NODROP)))
- var/datum/crafting_recipe/recipe_to_use = /datum/crafting_recipe/stunprod
- user.balloon_alert(user, "crafting cattleprod...")
- if(do_after(user, initial(recipe_to_use.time), src))
- var/obj/item/melee/baton/security/cattleprod/prod = new
-
- remove_item_from_storage(user)
-
- qdel(attacking_item)
- qdel(src)
-
- user.put_in_hands(prod)
- user.balloon_alert(user, "crafted cattleprod")
- return
- return ..()
-
-
/obj/item/throwing_star
name = "throwing star"
desc = "An ancient weapon still used to this day, due to its ease of lodging itself into its victim's body parts."
diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm
index 524c189acc6..a06b7fdaea7 100644
--- a/code/game/objects/obj_defense.dm
+++ b/code/game/objects/obj_defense.dm
@@ -145,7 +145,7 @@
if(has_buckled_mobs())
for(var/m in buckled_mobs)
var/mob/living/buckled_mob = m
- buckled_mob.electrocute_act((clamp(round(strength/400), 10, 90) + rand(-5, 5)), src, flags = SHOCK_TESLA)
+ buckled_mob.electrocute_act((clamp(round(strength * 3.125e-6), 10, 90) + rand(-5, 5)), src, flags = SHOCK_TESLA)
///the obj is deconstructed into pieces, whether through careful disassembly or when destroyed.
/obj/proc/deconstruct(disassembled = TRUE)
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 71d15fb3f58..ba8623ec4aa 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -63,6 +63,6 @@
/obj/structure/zap_act(power, zap_flags)
if(zap_flags & ZAP_OBJ_DAMAGE)
- take_damage(power/8000, BURN, "energy")
- power -= power/2000 //walls take a lot out of ya
+ take_damage(power * 1.5625e-7, BURN, "energy")
+ power -= power * 5e-4 //walls take a lot out of ya
. = ..()
diff --git a/code/game/objects/structures/icemoon/cave_entrance.dm b/code/game/objects/structures/icemoon/cave_entrance.dm
index 10f7a56c7f9..7393c20758e 100644
--- a/code/game/objects/structures/icemoon/cave_entrance.dm
+++ b/code/game/objects/structures/icemoon/cave_entrance.dm
@@ -102,7 +102,7 @@ GLOBAL_LIST_INIT(ore_probability, list(
mob_types = list(/mob/living/basic/mining/ice_whelp)
/obj/structure/spawner/ice_moon/demonic_portal/snowlegion
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/portal)
+ mob_types = list(/mob/living/basic/mining/legion/snow/spawner_made)
/obj/effect/collapsing_demonic_portal
name = "collapsing demonic portal"
diff --git a/code/game/objects/structures/lavaland/necropolis_tendril.dm b/code/game/objects/structures/lavaland/necropolis_tendril.dm
index 542df563a1f..22f7f0422cd 100644
--- a/code/game/objects/structures/lavaland/necropolis_tendril.dm
+++ b/code/game/objects/structures/lavaland/necropolis_tendril.dm
@@ -23,7 +23,7 @@
mob_types = list(/mob/living/basic/mining/goliath)
/obj/structure/spawner/lavaland/legion
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril)
+ mob_types = list(/mob/living/basic/mining/legion/spawner_made)
/obj/structure/spawner/lavaland/icewatcher
mob_types = list(/mob/living/basic/mining/watcher/icewing)
diff --git a/code/game/objects/structures/spawner.dm b/code/game/objects/structures/spawner.dm
index 7bbafd21ff2..340bcf212de 100644
--- a/code/game/objects/structures/spawner.dm
+++ b/code/game/objects/structures/spawner.dm
@@ -80,8 +80,8 @@
/mob/living/basic/mining/basilisk,
/mob/living/basic/mining/goldgrub,
/mob/living/basic/mining/goliath/ancient,
+ /mob/living/basic/mining/legion,
/mob/living/basic/wumborian_fugu,
- /mob/living/simple_animal/hostile/asteroid/hivelord,
)
faction = list(FACTION_MINING)
@@ -98,7 +98,7 @@
/obj/structure/spawner/mining/hivelord
name = "hivelord den"
desc = "A den housing a nest of hivelords."
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord)
+ mob_types = list(/mob/living/basic/mining/hivelord)
/obj/structure/spawner/mining/basilisk
name = "basilisk den"
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index b991bc0c274..6ba07a90e68 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -591,6 +591,12 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sink/kitchen, (-16))
var/busy = FALSE //Something's being washed at the moment
var/dispensedreagent = /datum/reagent/water // for whenever plumbing happens
+/obj/structure/water_source/Initialize(mapload)
+ . = ..()
+
+ create_reagents(INFINITY, NO_REACT)
+ reagents.add_reagent(dispensedreagent, INFINITY)
+
/obj/structure/water_source/attack_hand(mob/living/user, list/modifiers)
. = ..()
if(.)
diff --git a/code/game/say.dm b/code/game/say.dm
index a531ee02527..c0e9d4ff8ef 100644
--- a/code/game/say.dm
+++ b/code/game/say.dm
@@ -108,7 +108,7 @@ GLOBAL_LIST_INIT(freqtospan, list(
filter += tts_filter.Join(",")
if(voice && found_client)
- INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), src, html_decode(tts_message_to_use), message_language, voice, filter.Join(","), listened, message_range = range, pitch = pitch, silicon = tts_silicon_voice_effect)
+ INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), src, html_decode(tts_message_to_use), message_language, voice, filter.Join(","), listened, message_range = range, pitch = pitch)
/atom/movable/proc/compose_message(atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, list/message_mods = list(), visible_name = FALSE)
//This proc uses [] because it is faster than continually appending strings. Thanks BYOND.
diff --git a/code/game/turfs/open/planet.dm b/code/game/turfs/open/planet.dm
index 88f9518a08e..e5ab02c0924 100644
--- a/code/game/turfs/open/planet.dm
+++ b/code/game/turfs/open/planet.dm
@@ -14,6 +14,13 @@
heavyfootstep = FOOTSTEP_GENERIC_HEAVY
tiled_dirt = FALSE
+/turf/open/misc/dirt/station
+ name = "dirt flooring" //FOR THE LOVE OF GOD USE THIS INSTEAD OF DIRT FOR STATION MAPS
+ desc = "You heard this place was dirty, but this is just absurd."
+ baseturfs = /turf/open/floor/plating
+ initial_gas_mix = OPENTURF_LOW_PRESSURE
+ planetary_atmos = FALSE
+
/turf/open/misc/dirt/dark
icon_state = "greenerdirt"
base_icon_state = "greenerdirt"
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 0b731c61373..7f135cdbefb 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -117,7 +117,7 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list(
/datum/admins/proc/station_traits_panel,
// Client procs
/client/proc/admin_away,
- /client/proc/add_mob_ability,
+ /client/proc/add_marked_mob_ability,
/client/proc/admin_change_sec_level,
/client/proc/cinematic,
/client/proc/cmd_admin_add_freeform_ai_law,
@@ -132,7 +132,7 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list(
/client/proc/mass_zombie_infection,
/client/proc/object_say,
/client/proc/polymorph_all,
- /client/proc/remove_mob_ability,
+ /client/proc/remove_marked_mob_ability,
/client/proc/reset_ooc,
/client/proc/run_weather,
/client/proc/set_dynex_scale,
@@ -718,6 +718,80 @@ GLOBAL_PROTECT(admin_verbs_poll)
set category = "Debug"
SStrading_card_game.printAllCards()
+/client/proc/give_mob_action(mob/ability_recipient in GLOB.mob_list)
+ set category = "Admin.Fun"
+ set name = "Give Mob Action"
+ set desc = "Gives a mob ability to a mob."
+
+ var/static/list/all_mob_actions = sort_list(subtypesof(/datum/action/cooldown/mob_cooldown), GLOBAL_PROC_REF(cmp_typepaths_asc))
+ var/static/list/actions_by_name = list()
+ if (!length(actions_by_name))
+ for (var/datum/action/cooldown/mob_cooldown as anything in all_mob_actions)
+ actions_by_name["[initial(mob_cooldown.name)] ([mob_cooldown])"] = mob_cooldown
+
+ var/ability = tgui_input_list(usr, "Choose an ability", "Ability", actions_by_name)
+ if(isnull(ability))
+ return
+
+ var/ability_type = actions_by_name[ability]
+ var/datum/action/cooldown/mob_cooldown/add_ability
+
+ var/make_sequence = tgui_alert(usr, "Would you like this action to be a sequence of multiple abilities?", "Sequence Ability", list("Yes", "No"))
+ if(make_sequence == "Yes")
+ add_ability = new /datum/action/cooldown/mob_cooldown(ability_recipient)
+ add_ability.sequence_actions = list()
+ while(!isnull(ability_type))
+ var/ability_delay = tgui_input_number(usr, "Enter the delay in seconds before the next ability in the sequence is used", "Ability Delay", 2)
+ if(isnull(ability_delay) || ability_delay < 0)
+ ability_delay = 0
+ add_ability.sequence_actions[ability_type] = ability_delay * 1 SECONDS
+ ability = tgui_input_list(usr, "Choose a new sequence ability", "Sequence Ability", actions_by_name)
+ ability_type = actions_by_name[ability]
+ var/ability_cooldown = tgui_input_number(usr, "Enter the sequence abilities cooldown in seconds", "Ability Cooldown", 2)
+ if(isnull(ability_cooldown) || ability_cooldown < 0)
+ ability_cooldown = 2
+ add_ability.cooldown_time = ability_cooldown * 1 SECONDS
+ var/ability_melee_cooldown = tgui_input_number(usr, "Enter the abilities melee cooldown in seconds", "Melee Cooldown", 2)
+ if(isnull(ability_melee_cooldown) || ability_melee_cooldown < 0)
+ ability_melee_cooldown = 2
+ add_ability.melee_cooldown_time = ability_melee_cooldown * 1 SECONDS
+ add_ability.name = tgui_input_text(usr, "Choose ability name", "Ability name", "Generic Ability")
+ add_ability.create_sequence_actions()
+ else
+ add_ability = new ability_type(ability_recipient)
+
+ if(isnull(ability_recipient))
+ return
+ add_ability.Grant(ability_recipient)
+
+ message_admins("[key_name_admin(usr)] added mob ability [ability_type] to mob [ability_recipient].")
+ log_admin("[key_name(usr)] added mob ability [ability_type] to mob [ability_recipient].")
+ SSblackbox.record_feedback("tally", "admin_verb", 1, "Add Mob Ability") // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc!
+
+/client/proc/remove_mob_action(mob/removal_target in GLOB.mob_list)
+ set category = "Admin.Fun"
+ set name = "Remove Mob Action"
+ set desc = "Remove a special ability from the selected mob."
+
+ var/list/target_abilities = list()
+ for(var/datum/action/cooldown/mob_cooldown/ability in removal_target.actions)
+ target_abilities[ability.name] = ability
+
+ if(!length(target_abilities))
+ return
+
+ var/chosen_ability = tgui_input_list(usr, "Choose the spell to remove from [removal_target]", "Depower", sort_list(target_abilities))
+ if(isnull(chosen_ability))
+ return
+ var/datum/action/cooldown/mob_cooldown/to_remove = target_abilities[chosen_ability]
+ if(!istype(to_remove))
+ return
+
+ qdel(to_remove)
+ log_admin("[key_name(usr)] removed the ability [chosen_ability] from [key_name(removal_target)].")
+ message_admins("[key_name_admin(usr)] removed the ability [chosen_ability] from [key_name_admin(removal_target)].")
+ SSblackbox.record_feedback("tally", "admin_verb", 1, "Remove Mob Ability") // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc!
+
/client/proc/give_spell(mob/spell_recipient in GLOB.mob_list)
set category = "Admin.Fun"
set name = "Give Spell"
@@ -1036,8 +1110,6 @@ GLOBAL_PROTECT(admin_verbs_poll)
var/reqs = initial(spell.spell_requirements)
if(reqs & SPELL_CASTABLE_AS_BRAIN)
real_reqs += "Castable as brain"
- if(reqs & SPELL_CASTABLE_WHILE_PHASED)
- real_reqs += "Castable phased"
if(reqs & SPELL_REQUIRES_HUMAN)
real_reqs += "Must be human"
if(reqs & SPELL_REQUIRES_MIME_VOW)
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 624af957a84..f412f9d5a72 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -224,7 +224,7 @@
var/color = "#e6e6e6"
if(i%2 == 0)
color = "#f2f2f2"
- var/is_antagonist = is_special_character(M)
+ var/is_antagonist = is_special_character(M, allow_fake_antags = TRUE)
var/M_job = ""
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 7c2d34bd30f..9db6585799f 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -1309,16 +1309,16 @@
new /obj/effect/pod_landingzone(target, pod)
if (number == 1)
- log_admin("[key_name(usr)] created a [english_list(paths)]")
+ log_admin("[key_name(usr)] created an instance of [english_list(paths)]")
for(var/path in paths)
if(ispath(path, /mob))
- message_admins("[key_name_admin(usr)] created a [english_list(paths)]")
+ message_admins("[key_name_admin(usr)] created an instance of [english_list(paths)]")
break
else
- log_admin("[key_name(usr)] created [number]ea [english_list(paths)]")
+ log_admin("[key_name(usr)] created [number] instances of [english_list(paths)]")
for(var/path in paths)
if(ispath(path, /mob))
- message_admins("[key_name_admin(usr)] created [number]ea [english_list(paths)]")
+ message_admins("[key_name_admin(usr)] created [number] instances of [english_list(paths)]")
break
return
diff --git a/code/modules/admin/verbs/adminevents.dm b/code/modules/admin/verbs/adminevents.dm
index ca5458bdb1e..dd8f1d96f60 100644
--- a/code/modules/admin/verbs/adminevents.dm
+++ b/code/modules/admin/verbs/adminevents.dm
@@ -338,9 +338,9 @@
log_admin("[key_name(usr)] started weather of type [weather_type] on the z-level [z_level].")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Run Weather")
-/client/proc/add_mob_ability()
+/client/proc/add_marked_mob_ability()
set category = "Admin.Events"
- set name = "Add Mob Ability"
+ set name = "Add Mob Ability (Marked Mob)"
set desc = "Adds an ability to a marked mob."
if(!holder)
@@ -349,56 +349,11 @@
if(!isliving(holder.marked_datum))
to_chat(usr, span_warning("Error: Please mark a mob to add actions to it."))
return
+ give_mob_action(holder.marked_datum)
- var/mob/living/marked_mob = holder.marked_datum
-
- var/static/list/all_mob_actions = sort_list(subtypesof(/datum/action/cooldown/mob_cooldown), GLOBAL_PROC_REF(cmp_typepaths_asc))
- var/static/list/actions_by_name = list()
- if (!length(actions_by_name))
- for (var/datum/action/cooldown/mob_cooldown as anything in all_mob_actions)
- actions_by_name["[initial(mob_cooldown.name)] ([mob_cooldown])"] = mob_cooldown
-
- var/ability = tgui_input_list(usr, "Choose an ability", "Ability", actions_by_name)
- if(isnull(ability))
- return
-
- var/ability_type = actions_by_name[ability]
- var/datum/action/cooldown/mob_cooldown/add_ability
-
- var/make_sequence = tgui_alert(usr, "Would you like this action to be a sequence of multiple abilities?", "Sequence Ability", list("Yes", "No"))
- if(make_sequence == "Yes")
- add_ability = new /datum/action/cooldown/mob_cooldown(marked_mob)
- add_ability.sequence_actions = list()
- while(!isnull(ability_type))
- var/ability_delay = tgui_input_number(usr, "Enter the delay in seconds before the next ability in the sequence is used", "Ability Delay", 2)
- if(isnull(ability_delay) || ability_delay < 0)
- ability_delay = 0
- add_ability.sequence_actions[ability_type] = ability_delay * 1 SECONDS
- ability_type = tgui_input_list(usr, "Choose a new sequence ability", "Sequence Ability", all_mob_actions)
- var/ability_cooldown = tgui_input_number(usr, "Enter the sequence abilities cooldown in seconds", "Ability Cooldown", 2)
- if(isnull(ability_cooldown) || ability_cooldown < 0)
- ability_cooldown = 2
- add_ability.cooldown_time = ability_cooldown * 1 SECONDS
- var/ability_melee_cooldown = tgui_input_number(usr, "Enter the abilities melee cooldown in seconds", "Melee Cooldown", 2)
- if(isnull(ability_melee_cooldown) || ability_melee_cooldown < 0)
- ability_melee_cooldown = 2
- add_ability.melee_cooldown_time = ability_melee_cooldown * 1 SECONDS
- add_ability.name = tgui_input_text(usr, "Choose ability name", "Ability name", "Generic Ability")
- add_ability.create_sequence_actions()
- else
- add_ability = new ability_type(marked_mob)
-
- if(isnull(marked_mob))
- return
- add_ability.Grant(marked_mob)
-
- message_admins("[key_name_admin(usr)] added mob ability [ability_type] to mob [marked_mob].")
- log_admin("[key_name(usr)] added mob ability [ability_type] to mob [marked_mob].")
- SSblackbox.record_feedback("tally", "admin_verb", 1, "Add Mob Ability") // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc!
-
-/client/proc/remove_mob_ability()
+/client/proc/remove_marked_mob_ability()
set category = "Admin.Events"
- set name = "Remove Mob Ability"
+ set name = "Remove Mob Ability (Marked Mob)"
set desc = "Removes an ability from marked mob."
if(!holder)
@@ -407,24 +362,7 @@
if(!isliving(holder.marked_datum))
to_chat(usr, span_warning("Error: Please mark a mob to remove actions from it."))
return
-
- var/mob/living/marked_mob = holder.marked_datum
-
- var/list/all_mob_actions = list()
- for(var/datum/action/cooldown/mob_cooldown/ability in marked_mob.actions)
- all_mob_actions.Add(ability)
-
- var/datum/action/cooldown/mob_cooldown/ability = tgui_input_list(usr, "Remove an ability", "Ability", all_mob_actions)
-
- if(!ability)
- return
-
- var/ability_name = ability.name
- QDEL_NULL(ability)
-
- message_admins("[key_name_admin(usr)] removed ability [ability_name] from mob [marked_mob].")
- log_admin("[key_name(usr)] removed mob ability [ability_name] from mob [marked_mob].")
- SSblackbox.record_feedback("tally", "admin_verb", 1, "Remove Mob Ability") // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc!
+ remove_mob_action(holder.marked_datum)
/client/proc/command_report_footnote()
diff --git a/code/modules/admin/verbs/admingame.dm b/code/modules/admin/verbs/admingame.dm
index 8bc58a7876c..317c8fafd3b 100644
--- a/code/modules/admin/verbs/admingame.dm
+++ b/code/modules/admin/verbs/admingame.dm
@@ -233,7 +233,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
new_character.real_name = record_found.name
new_character.gender = lowertext(record_found.gender)
new_character.age = record_found.age
- var/datum/dna/found_dna = record_found.dna_ref
+ var/datum/dna/found_dna = record_found.locked_dna
new_character.hardset_dna(found_dna.unique_identity, found_dna.mutation_index, null, record_found.name, record_found.blood_type, new record_found.species_type, found_dna.features)
else
new_character.randomize_human_appearance()
diff --git a/code/modules/admin/verbs/grant_dna_infusion.dm b/code/modules/admin/verbs/grant_dna_infusion.dm
new file mode 100644
index 00000000000..06cfa8110d6
--- /dev/null
+++ b/code/modules/admin/verbs/grant_dna_infusion.dm
@@ -0,0 +1,36 @@
+/*
+ * Attempts to grant the target all organs from a given DNA infuser entry.area
+ * Returns the entry if all organs were successfully replaced.
+ * If no infusion was picked, the infusion had no organs, or if one or more organs could not be granted, returns FALSE
+*/
+/client/proc/grant_dna_infusion(mob/living/carbon/human/target in world)
+ set name = "Apply DNA Infusion"
+ set category = "Debug"
+
+ var/list/infusions = list()
+ for(var/datum/infuser_entry/path as anything in subtypesof(/datum/infuser_entry))
+ var/str = "[initial(path.name)] ([path])"
+ infusions[str] = path
+
+ var/datum/infuser_entry/picked_infusion = tgui_input_list(usr, "Select infusion", "Apply DNA Infusion", infusions)
+
+ if(isnull(picked_infusion))
+ return FALSE
+
+ // This is necessary because list propererties are not defined until initialization
+ picked_infusion = infusions[picked_infusion]
+ picked_infusion = new picked_infusion
+
+ if(!length(picked_infusion.output_organs))
+ return FALSE
+
+ . = picked_infusion
+ for(var/obj/item/organ/infusion_organ as anything in picked_infusion.output_organs)
+ var/obj/item/organ/new_organ = new infusion_organ()
+ if(!new_organ.replace_into(target))
+ to_chat(usr, span_notice("[target] is unable to carry [new_organ]!"))
+ qdel(new_organ)
+ . = FALSE
+ continue
+ log_admin("[key_name(usr)] has added organ [new_organ.type] to [key_name(target)]")
+ message_admins("[key_name_admin(usr)] has added organ [new_organ.type] to [ADMIN_LOOKUPFLW(target)]")
diff --git a/code/modules/admin/verbs/secrets.dm b/code/modules/admin/verbs/secrets.dm
index a03d61d426e..e29ed6404e4 100644
--- a/code/modules/admin/verbs/secrets.dm
+++ b/code/modules/admin/verbs/secrets.dm
@@ -220,7 +220,7 @@ GLOBAL_DATUM(everyone_a_traitor, /datum/everyone_is_a_traitor_controller)
var/result = input(holder, "Please choose a new species","Species") as null|anything in GLOB.species_list
if(result)
SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Mass Species Change", "[result]"))
- log_admin("[key_name(holder)] turned all humans into [result]", 1)
+ log_admin("[key_name(holder)] turned all humans into [result]")
message_admins("\blue [key_name_admin(holder)] turned all humans into [result]")
var/newtype = GLOB.species_list[result]
for(var/i in GLOB.human_list)
@@ -230,21 +230,21 @@ GLOBAL_DATUM(everyone_a_traitor, /datum/everyone_is_a_traitor_controller)
if(!is_funmin)
return
SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Power All APCs"))
- log_admin("[key_name(holder)] made all areas powered", 1)
+ log_admin("[key_name(holder)] made all areas powered")
message_admins(span_adminnotice("[key_name_admin(holder)] made all areas powered"))
power_restore()
if("unpower")
if(!is_funmin)
return
SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Depower All APCs"))
- log_admin("[key_name(holder)] made all areas unpowered", 1)
+ log_admin("[key_name(holder)] made all areas unpowered")
message_admins(span_adminnotice("[key_name_admin(holder)] made all areas unpowered"))
power_failure()
if("quickpower")
if(!is_funmin)
return
SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Power All SMESs"))
- log_admin("[key_name(holder)] made all SMESs powered", 1)
+ log_admin("[key_name(holder)] made all SMESs powered")
message_admins(span_adminnotice("[key_name_admin(holder)] made all SMESs powered"))
power_restore_quick()
if("anon_name")
diff --git a/code/modules/admin/view_variables/reference_tracking.dm b/code/modules/admin/view_variables/reference_tracking.dm
index a5b2af68c77..9cb661d2fee 100644
--- a/code/modules/admin/view_variables/reference_tracking.dm
+++ b/code/modules/admin/view_variables/reference_tracking.dm
@@ -92,6 +92,7 @@
return
datum_container.last_find_references = search_time
+ var/container_print = datum_container.ref_search_details()
var/list/vars_list = datum_container.vars
for(var/varname in vars_list)
@@ -108,11 +109,11 @@
found_refs[varname] = TRUE
continue //End early, don't want these logging
#endif
- log_reftracker("Found [type] [text_ref(src)] in [datum_container.type]'s [text_ref(datum_container)] [varname] var. [container_name]")
+ log_reftracker("Found [type] [text_ref(src)] in [datum_container.type]'s [container_print] [varname] var. [container_name]")
continue
if(islist(variable))
- DoSearchVar(variable, "[container_name] [text_ref(datum_container)] -> [varname] (list)", recursive_limit - 1, search_time)
+ DoSearchVar(variable, "[container_name] [container_print] -> [varname] (list)", recursive_limit - 1, search_time)
else if(islist(potential_container))
var/normal = IS_NORMAL_LIST(potential_container)
@@ -159,3 +160,13 @@
qdel(src, force)
#endif
+
+// Kept outside the ifdef so overrides are easy to implement
+
+/// Return info about us for reference searching purposes
+/// Will be logged as a representation of this datum if it's a part of a search chain
+/datum/proc/ref_search_details()
+ return text_ref(src)
+
+/datum/callback/ref_search_details()
+ return "[text_ref(src)] (obj: [object] proc: [delegate] args: [json_encode(arguments)] user: [user?.resolve() || "null"])"
diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm
index 5bbbfaa40b8..a435756b456 100644
--- a/code/modules/antagonists/_common/antag_datum.dm
+++ b/code/modules/antagonists/_common/antag_datum.dm
@@ -54,7 +54,7 @@ GLOBAL_LIST_EMPTY(antagonists)
/// The typepath for the outfit to show in the preview for the preferences menu.
var/preview_outfit
/// Flags for antags to turn on or off and check!
- var/antag_flags = FLAG_ANTAG_CAN_BE_INDUCTED
+ var/antag_flags = FLAG_FAKE_ANTAG
/// If true, this antagonist can assign themself a new objective
var/can_assign_self_objectives = FALSE
/// Default to fill in when entering a custom objective.
diff --git a/code/modules/antagonists/abductor/equipment/glands/electric.dm b/code/modules/antagonists/abductor/equipment/glands/electric.dm
index acb1505a71c..9c4d47dc337 100644
--- a/code/modules/antagonists/abductor/equipment/glands/electric.dm
+++ b/code/modules/antagonists/abductor/equipment/glands/electric.dm
@@ -22,5 +22,5 @@
addtimer(CALLBACK(src, PROC_REF(zap)), rand(30, 100))
/obj/item/organ/internal/heart/gland/electric/proc/zap()
- tesla_zap(owner, 4, 8000, ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_MOB_STUN)
+ tesla_zap(owner, 4, 3.2e6, ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_MOB_STUN)
playsound(get_turf(owner), 'sound/magic/lightningshock.ogg', 50, TRUE)
diff --git a/code/modules/antagonists/blob/structures/_blob.dm b/code/modules/antagonists/blob/structures/_blob.dm
index 3580e3f3bf8..543da00d2f5 100644
--- a/code/modules/antagonists/blob/structures/_blob.dm
+++ b/code/modules/antagonists/blob/structures/_blob.dm
@@ -227,10 +227,10 @@
/obj/structure/blob/zap_act(power, zap_flags)
if(overmind)
if(overmind.blobstrain.tesla_reaction(src, power))
- take_damage(power * 0.0025, BURN, ENERGY)
+ take_damage(power * 3.125e-6, BURN, ENERGY)
else
- take_damage(power * 0.0025, BURN, ENERGY)
- power -= power * 0.0025 //You don't get to do it for free
+ take_damage(power * 3.125e-6, BURN, ENERGY)
+ power -= power * 2.5e-3 //You don't get to do it for free
return ..() //You don't get to do it for free
/obj/structure/blob/extinguish()
diff --git a/code/modules/antagonists/changeling/powers/absorb.dm b/code/modules/antagonists/changeling/powers/absorb.dm
index c2ae89933d1..cee0f0da5b9 100644
--- a/code/modules/antagonists/changeling/powers/absorb.dm
+++ b/code/modules/antagonists/changeling/powers/absorb.dm
@@ -95,31 +95,14 @@
//Some of target's recent speech, so the changeling can attempt to imitate them better.
//Recent as opposed to all because rounds tend to have a LOT of text.
- var/list/recent_speech = list()
- var/list/say_log = list()
- var/log_source = target.logging
- for(var/log_type in log_source)
- var/nlog_type = text2num(log_type)
- if(nlog_type & LOG_SAY)
- var/list/reversed = log_source[log_type]
- if(islist(reversed))
- say_log = reverse_range(reversed.Copy())
- break
-
- if(LAZYLEN(say_log) > LING_ABSORB_RECENT_SPEECH)
- recent_speech = say_log.Copy(say_log.len-LING_ABSORB_RECENT_SPEECH+1,0) //0 so len-LING_ARS+1 to end of list
- else
- for(var/spoken_memory in say_log)
- if(recent_speech.len >= LING_ABSORB_RECENT_SPEECH)
- break
- recent_speech[spoken_memory] = splittext(say_log[spoken_memory], "\"", 1, 0, TRUE)[3]
+ var/list/recent_speech = target.copy_recent_speech()
if(recent_speech.len)
changeling.antag_memory += "Some of [target]'s speech patterns, we should study these to better impersonate [target.p_them()]!
"
to_chat(owner, span_boldnotice("Some of [target]'s speech patterns, we should study these to better impersonate [target.p_them()]!"))
for(var/spoken_memory in recent_speech)
- changeling.antag_memory += "\"[recent_speech[spoken_memory]]\"
"
- to_chat(owner, span_notice("\"[recent_speech[spoken_memory]]\""))
+ changeling.antag_memory += "\"[spoken_memory]\"
"
+ to_chat(owner, span_notice("\"[spoken_memory]\""))
changeling.antag_memory += "We have no more knowledge of [target]'s speech patterns.
"
to_chat(owner, span_boldnotice("We have no more knowledge of [target]'s speech patterns."))
diff --git a/code/modules/antagonists/changeling/powers/panacea.dm b/code/modules/antagonists/changeling/powers/panacea.dm
index 25a267e03df..9fe7613cc4c 100644
--- a/code/modules/antagonists/changeling/powers/panacea.dm
+++ b/code/modules/antagonists/changeling/powers/panacea.dm
@@ -14,7 +14,9 @@
var/list/bad_organs = list(
user.get_organ_by_type(/obj/item/organ/internal/empowered_borer_egg), // SKYRAT EDIT ADDITION
user.get_organ_by_type(/obj/item/organ/internal/body_egg),
- user.get_organ_by_type(/obj/item/organ/internal/zombie_infection))
+ user.get_organ_by_type(/obj/item/organ/internal/legion_tumour),
+ user.get_organ_by_type(/obj/item/organ/internal/zombie_infection),
+ )
try_to_mutant_cure(user) //SKYRAT EDIT ADDITION
diff --git a/code/modules/antagonists/ert/ert.dm b/code/modules/antagonists/ert/ert.dm
index 0088660ec14..116d19f5164 100644
--- a/code/modules/antagonists/ert/ert.dm
+++ b/code/modules/antagonists/ert/ert.dm
@@ -12,8 +12,8 @@
antagpanel_category = ANTAG_GROUP_ERT
suicide_cry = "FOR NANOTRASEN!!"
count_against_dynamic_roll_chance = FALSE
- // Not 'true' antags, cannot induct to prevent issues
- antag_flags = NONE
+ // Not 'true' antags, this disables certain interactions that assume the owner is a baddie
+ antag_flags = FLAG_FAKE_ANTAG
var/datum/team/ert/ert_team
var/leader = FALSE
var/datum/outfit/outfit = /datum/outfit/centcom/ert/security
diff --git a/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm b/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm
index 9e4d77bd95c..4a4e9045185 100644
--- a/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm
+++ b/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm
@@ -253,7 +253,7 @@
var/mob/living/basic/heretic_summon/star_gazer/star_gazer_mob = new /mob/living/basic/heretic_summon/star_gazer(loc)
star_gazer_mob.maxHealth = INFINITY
star_gazer_mob.health = INFINITY
- user.AddElement(/datum/element/death_linked, star_gazer_mob)
+ user.AddComponent(/datum/component/death_linked, star_gazer_mob)
star_gazer_mob.AddComponent(/datum/component/obeys_commands, star_gazer_commands)
star_gazer_mob.AddComponent(/datum/component/damage_aura, range = 7, burn_damage = 0.5, simple_damage = 0.5, immune_factions = list(FACTION_HERETIC), current_owner = user)
star_gazer_mob.befriend(user)
diff --git a/code/modules/antagonists/heretic/magic/star_touch.dm b/code/modules/antagonists/heretic/magic/star_touch.dm
index de3a56128de..ba8c2a56391 100644
--- a/code/modules/antagonists/heretic/magic/star_touch.dm
+++ b/code/modules/antagonists/heretic/magic/star_touch.dm
@@ -73,11 +73,13 @@
/obj/item/melee/touch_attack/star_touch/Initialize(mapload)
. = ..()
- AddComponent(/datum/component/effect_remover, \
+ AddComponent(\
+ /datum/component/effect_remover, \
success_feedback = "You remove %THEEFFECT.", \
tip_text = "Clear rune", \
on_clear_callback = CALLBACK(src, PROC_REF(after_clear_rune)), \
- effects_we_clear = list(/obj/effect/cosmic_rune))
+ effects_we_clear = list(/obj/effect/cosmic_rune), \
+ )
/*
* Callback for effect_remover component.
diff --git a/code/modules/antagonists/heretic/structures/knock_final.dm b/code/modules/antagonists/heretic/structures/knock_final.dm
index 85face85609..c8a2058eb9f 100644
--- a/code/modules/antagonists/heretic/structures/knock_final.dm
+++ b/code/modules/antagonists/heretic/structures/knock_final.dm
@@ -5,39 +5,68 @@
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
icon = 'icons/obj/anomaly.dmi'
icon_state = "bhole3"
- color = "#53277E"
- light_color = "#53277E" //cooler purple
+ color = COLOR_VOID_PURPLE
+ light_color = COLOR_VOID_PURPLE
light_range = 20
anchored = TRUE
density = FALSE
layer = HIGH_PIPE_LAYER //0.01 above sigil layer used by heretic runes
move_resist = INFINITY
+ /// Who is our daddy?
var/datum/mind/ascendee
- ///a static list of heretic summons, this shouldnt even matter enough to be static but whatever
+ /// True if we're currently checking for ghost opinions
+ var/gathering_candidates = TRUE
+ ///a static list of heretic summons we cam create, automatically populated from heretic monster subtypes
var/static/list/monster_types
+ /// A static list of heretic summons which we should not create
+ var/static/list/monster_types_blacklist = list(
+ /mob/living/basic/heretic_summon/star_gazer,
+ /mob/living/simple_animal/hostile/heretic_summon/armsy,
+ /mob/living/simple_animal/hostile/heretic_summon/armsy/prime,
+ )
-/obj/structure/knock_tear/Initialize(mapload, ascendant)
+/obj/structure/knock_tear/Initialize(mapload, datum/mind/ascendant_mind)
. = ..()
transform *= 3
- if(!monster_types)
- monster_types = subtypesof(/mob/living/simple_animal/hostile/heretic_summon) - /mob/living/simple_animal/hostile/heretic_summon/armsy/prime
- if(ascendant)
- ascendee = ascendant
+ if(isnull(monster_types))
+ monster_types = subtypesof(/mob/living/simple_animal/hostile/heretic_summon) + subtypesof(/mob/living/basic/heretic_summon) - monster_types_blacklist
+ if(!isnull(ascendant_mind))
+ ascendee = ascendant_mind
+ RegisterSignals(ascendant_mind.current, list(COMSIG_LIVING_DEATH, COMSIG_QDELETING), PROC_REF(end_madness))
SSpoints_of_interest.make_point_of_interest(src)
INVOKE_ASYNC(src, PROC_REF(poll_ghosts))
+/// Ask ghosts if they want to make some noise
/obj/structure/knock_tear/proc/poll_ghosts()
var/list/candidates = poll_ghost_candidates("Would you like to be a random eldritch monster attacking the crew?", ROLE_SENTIENCE, ROLE_SENTIENCE, 10 SECONDS, POLL_IGNORE_HERETIC_MONSTER)
while(LAZYLEN(candidates))
var/mob/dead/observer/candidate = pick_n_take(candidates)
ghost_to_monster(candidate, should_ask = FALSE)
+ gathering_candidates = FALSE
+
+/// Destroy the rift if you kill the heretic
+/obj/structure/knock_tear/proc/end_madness(datum/former_master)
+ SIGNAL_HANDLER
+ var/turf/our_turf = get_turf(src)
+ playsound(our_turf, 'sound/magic/castsummon.ogg', vol = 100, vary = TRUE)
+ visible_message(span_boldwarning("The rip in space spasms and disappears!"))
+ UnregisterSignal(former_master, list(COMSIG_LIVING_DEATH, COMSIG_QDELETING)) // Just in case they die THEN delete
+ new /obj/effect/temp_visual/destabilising_tear(our_turf)
+ qdel(src)
/obj/structure/knock_tear/attack_ghost(mob/user)
. = ..()
- if(.)
+ if(. || gathering_candidates)
return
ghost_to_monster(user)
+/obj/structure/knock_tear/examine(mob/user)
+ . = ..()
+ if (!isobserver(user) || gathering_candidates)
+ return
+ . += span_notice("You can use this to enter the world as a foul monster.")
+
+/// Turn a ghost into an 'orrible beast
/obj/structure/knock_tear/proc/ghost_to_monster(mob/dead/observer/user, should_ask = TRUE)
if(should_ask)
var/ask = tgui_alert(user, "Become a monster?", "Ascended Rift", list("Yes", "No"))
@@ -61,7 +90,26 @@
/obj/structure/knock_tear/move_crushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
return FALSE
-/obj/structure/knock_tear/Destroy(force) //this shouldnt happen but hey
+/obj/structure/knock_tear/Destroy(force)
if(ascendee)
ascendee = null
return ..()
+
+/obj/effect/temp_visual/destabilising_tear
+ name = "destabilised tear"
+ icon = 'icons/obj/anomaly.dmi'
+ icon_state = "bhole3"
+ color = COLOR_VOID_PURPLE
+ light_color = COLOR_VOID_PURPLE
+ light_range = 20
+ layer = HIGH_PIPE_LAYER
+ duration = 1 SECONDS
+
+/obj/effect/temp_visual/destabilising_tear/Initialize(mapload)
+ . = ..()
+ transform *= 3
+ animate(src, transform = matrix().Scale(3.2), time = 0.15 SECONDS)
+ animate(transform = matrix().Scale(0.2), time = 0.75 SECONDS)
+ animate(transform = matrix().Scale(3, 0), time = 0.1 SECONDS)
+ animate(src, color = COLOR_WHITE, time = 0.25 SECONDS, flags = ANIMATION_PARALLEL)
+ animate(color = COLOR_VOID_PURPLE, time = 0.3 SECONDS)
diff --git a/code/modules/antagonists/malf_ai/malf_ai_modules.dm b/code/modules/antagonists/malf_ai/malf_ai_modules.dm
index a6c6616ad48..49d464fde16 100644
--- a/code/modules/antagonists/malf_ai/malf_ai_modules.dm
+++ b/code/modules/antagonists/malf_ai/malf_ai_modules.dm
@@ -9,7 +9,6 @@
#define MALF_AI_ROLL_COOLDOWN 1 SECONDS + MALF_AI_ROLL_TIME
#define MALF_AI_ROLL_DAMAGE 75
#define MALF_AI_ROLL_CRIT_CHANCE 5 //percent
-#define MALF_AI_ROLL_MAX_DISTANCE 1 //anything further away than this, and the roll will fail
GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/obj/machinery/field/containment,
@@ -1138,6 +1137,11 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module))
enable_text = span_notice("Your inner servos shift as you prepare to roll around. Click adjacent tiles to roll onto them!")
disable_text = span_notice("You disengage your rolling protocols.")
+ /// How long does it take for us to roll?
+ var/roll_over_time = MALF_AI_ROLL_TIME
+ /// On top of [roll_over_time], how long does it take for the ability to cooldown?
+ var/roll_over_cooldown = MALF_AI_ROLL_COOLDOWN
+
/datum/action/innate/ai/ranged/core_tilt/New()
. = ..()
desc = "[desc] It has [uses] use\s remaining."
@@ -1152,7 +1156,7 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module))
return FALSE
var/mob/living/silicon/ai/ai_caller = caller
- if (ai_caller.incapacitated())
+ if (ai_caller.incapacitated() || !isturf(ai_caller.loc))
return FALSE
var/turf/target = get_turf(clicked_on)
@@ -1163,30 +1167,32 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module))
target.balloon_alert(ai_caller, "can't roll on yourself!")
return FALSE
- if (get_dist(ai_caller, target) > MALF_AI_ROLL_MAX_DISTANCE)
- target.balloon_alert(ai_caller, "too far!")
- return FALSE
-
var/picked_dir = get_dir(ai_caller, target)
+ if (!picked_dir)
+ return FALSE
+ var/turf/temp_target = get_step(ai_caller, picked_dir) // we can move during the timer so we cant just pass the ref
- new /obj/effect/temp_visual/telegraphing/vending_machine_tilt(target, MALF_AI_ROLL_TIME)
+ new /obj/effect/temp_visual/telegraphing/vending_machine_tilt(temp_target, roll_over_time)
ai_caller.balloon_alert_to_viewers("rolling...")
- addtimer(CALLBACK(src, PROC_REF(do_roll_over), ai_caller, picked_dir), MALF_AI_ROLL_TIME)
+ addtimer(CALLBACK(src, PROC_REF(do_roll_over), ai_caller, picked_dir), roll_over_time)
adjust_uses(-1)
if(uses)
desc = "[initial(desc)] It has [uses] use\s remaining."
build_all_button_icons()
- COOLDOWN_START(src, time_til_next_tilt, MALF_AI_ROLL_COOLDOWN)
+ COOLDOWN_START(src, time_til_next_tilt, roll_over_cooldown)
/datum/action/innate/ai/ranged/core_tilt/proc/do_roll_over(mob/living/silicon/ai/ai_caller, picked_dir)
+ if (ai_caller.incapacitated() || !isturf(ai_caller.loc)) // prevents bugs where the ai is carded and rolls
+ return
+
var/turf/target = get_step(ai_caller, picked_dir) // in case we moved we pass the dir not the target turf
if (isnull(target))
return
- var/paralyze_time = clamp(6 SECONDS, 0 SECONDS, (MALF_AI_ROLL_COOLDOWN * 0.9)) //the clamp prevents stunlocking as the max is always a little less than the cooldown between rolls
+ var/paralyze_time = clamp(6 SECONDS, 0 SECONDS, (roll_over_cooldown * 0.9)) //the clamp prevents stunlocking as the max is always a little less than the cooldown between rolls
return ai_caller.fall_and_crush(target, MALF_AI_ROLL_DAMAGE, MALF_AI_ROLL_CRIT_CHANCE, null, paralyze_time, picked_dir, rotation = get_rotation_from_dir(picked_dir))
@@ -1321,4 +1327,3 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module))
#undef MALF_AI_ROLL_TIME
#undef MALF_AI_ROLL_DAMAGE
#undef MALF_AI_ROLL_CRIT_CHANCE
-#undef MALF_AI_ROLL_MAX_DISTANCE
diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm
index e88730f7026..3e759bdc362 100644
--- a/code/modules/antagonists/revolution/revolution.dm
+++ b/code/modules/antagonists/revolution/revolution.dm
@@ -397,6 +397,9 @@
/// List of all ex-revs. Useful because dynamic removes antag status when it ends, so this can be kept for the roundend report.
var/list/ex_revs = list()
+ /// The objective of the heads of staff, aka to kill the headrevs.
+ var/list/datum/objective/mutiny/heads_objective = list()
+
/// Proc called on periodic timer.
/// Updates the rev team's objectives to make sure all heads are targets, useful when new heads latejoin.
/// Propagates all objectives to all revs.
@@ -472,11 +475,34 @@
/// Checks if heads have won
/datum/team/revolution/proc/check_heads_victory()
- for(var/datum/mind/rev_mind in get_head_revolutionaries())
- var/turf/rev_turf = get_turf(rev_mind.current)
- if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(rev_turf.z))
- return FALSE
- return TRUE
+ // List of headrevs we're currently tracking
+ var/list/included_headrevs = list()
+ // List of current headrevs
+ var/list/current_headrevs = get_head_revolutionaries()
+ // A copy of the head of staff objective list, since we're going to be modifying the original list.
+ var/list/heads_objective_copy = heads_objective.Copy()
+
+ var/objective_complete = TRUE
+ // Here, we check current head of staff objectives and remove them if the target doesn't exist as a headrev anymore
+ for(var/datum/objective/mutiny/objective in heads_objective_copy)
+ if(!(objective.target in current_headrevs))
+ heads_objective -= objective
+ continue
+ if(!objective.check_completion())
+ objective_complete = FALSE
+ included_headrevs += objective.target
+
+ // Here, we check current headrevs and add them as objectives if they didn't exist as a head of staff objective before.
+ // Additionally, we make sure the objective is not completed by running the check_completion check on them.
+ for(var/datum/mind/rev_mind as anything in current_headrevs)
+ if(!(rev_mind in included_headrevs))
+ var/datum/objective/mutiny/objective = new()
+ objective.target = rev_mind
+ if(!objective.check_completion())
+ objective_complete = FALSE
+ heads_objective += objective
+
+ return objective_complete
/// Updates the state of the world depending on if revs won or loss.
/// Returns who won, at which case this method should no longer be called.
diff --git a/code/modules/antagonists/traitor/objectives/abstract/target_player.dm b/code/modules/antagonists/traitor/objectives/abstract/target_player.dm
index 76471eb244a..c08f8cd46ee 100644
--- a/code/modules/antagonists/traitor/objectives/abstract/target_player.dm
+++ b/code/modules/antagonists/traitor/objectives/abstract/target_player.dm
@@ -16,3 +16,18 @@
/// The target that we need to target.
var/mob/living/target
+
+/datum/traitor_objective/target_player/Destroy(force)
+ set_target(null)
+ return ..()
+
+/datum/traitor_objective/target_player/proc/set_target(mob/living/new_target)
+ if(target)
+ UnregisterSignal(target, COMSIG_QDELETING)
+ target = new_target
+ if(target)
+ RegisterSignal(target, COMSIG_QDELETING, PROC_REF(target_deleted))
+
+/datum/traitor_objective/target_player/proc/target_deleted(datum/source)
+ SIGNAL_HANDLER
+ set_target(null)
diff --git a/code/modules/antagonists/traitor/objectives/assassination.dm b/code/modules/antagonists/traitor/objectives/assassination.dm
index 4efcbb111be..ab3211aedd8 100644
--- a/code/modules/antagonists/traitor/objectives/assassination.dm
+++ b/code/modules/antagonists/traitor/objectives/assassination.dm
@@ -107,20 +107,13 @@
return //in their pockets please
succeed_objective()
-/datum/traitor_objective/target_player/assassinate/calling_card/generate_objective(datum/mind/generating_for, list/possible_duplicates)
- . = ..()
- if(!.) //didn't generate
- return FALSE
- RegisterSignal(target, COMSIG_QDELETING, PROC_REF(on_target_qdeleted))
-
/datum/traitor_objective/target_player/assassinate/calling_card/ungenerate_objective()
- UnregisterSignal(target, COMSIG_QDELETING)
. = ..() //unsets kill target
if(card)
UnregisterSignal(card, COMSIG_ITEM_EQUIPPED)
card = null
-/datum/traitor_objective/target_player/assassinate/calling_card/on_target_qdeleted()
+/datum/traitor_objective/target_player/assassinate/calling_card/target_deleted()
//you cannot plant anything on someone who is gone gone, so even if this happens after you're still liable to fail
fail_objective(penalty_cost = telecrystal_penalty)
@@ -228,7 +221,7 @@
return FALSE //MISSION FAILED, WE'LL GET EM NEXT TIME
var/datum/mind/target_mind = pick(possible_targets)
- target = target_mind.current
+ set_target(target_mind.current)
replace_in_name("%TARGET%", target.real_name)
replace_in_name("%JOB TITLE%", target_mind.assigned_role.title)
RegisterSignal(target, COMSIG_LIVING_DEATH, PROC_REF(on_target_death))
@@ -236,17 +229,17 @@
/datum/traitor_objective/target_player/assassinate/ungenerate_objective()
UnregisterSignal(target, COMSIG_LIVING_DEATH)
- target = null
+ set_target(null)
///proc for checking for special states that invalidate a target
/datum/traitor_objective/target_player/assassinate/proc/special_target_filter(list/possible_targets)
return
-/datum/traitor_objective/target_player/assassinate/proc/on_target_qdeleted()
- SIGNAL_HANDLER
+/datum/traitor_objective/target_player/assassinate/target_deleted()
if(objective_state == OBJECTIVE_STATE_INACTIVE)
//don't take an objective target of someone who is already obliterated
fail_objective()
+ return ..()
/datum/traitor_objective/target_player/assassinate/proc/on_target_death()
SIGNAL_HANDLER
diff --git a/code/modules/antagonists/traitor/objectives/demoralise_assault.dm b/code/modules/antagonists/traitor/objectives/demoralise_assault.dm
index 095c646cb99..fe26864e4fc 100644
--- a/code/modules/antagonists/traitor/objectives/demoralise_assault.dm
+++ b/code/modules/antagonists/traitor/objectives/demoralise_assault.dm
@@ -55,9 +55,7 @@
/datum/traitor_objective/target_player/assault/ungenerate_objective()
UnregisterSignal(target, COMSIG_ATOM_WAS_ATTACKED)
UnregisterSignal(target, COMSIG_LIVING_DEATH)
- UnregisterSignal(target, COMSIG_QDELETING)
-
- target = null
+ set_target(null)
/datum/traitor_objective/target_player/assault/generate_objective(datum/mind/generating_for, list/possible_duplicates)
var/list/already_targeting = list() //List of minds we're already targeting. The possible_duplicates is a list of objectives, so let's not mix things
@@ -102,7 +100,7 @@
var/datum/mind/target_mind = pick(possible_targets)
- target = target_mind.current
+ set_target(target_mind.current)
replace_in_name("%TARGET%", target.real_name)
replace_in_name("%JOB TITLE%", target_mind.assigned_role.title)
@@ -110,7 +108,6 @@
replace_in_name("%COUNT%", attacks_required)
RegisterSignal(target, COMSIG_LIVING_DEATH, PROC_REF(on_target_death))
- RegisterSignal(target, COMSIG_QDELETING, PROC_REF(on_target_qdeleted))
return TRUE
@@ -120,11 +117,10 @@
buttons += add_ui_button("[attacks_required - attacks_inflicted]", "This tells you how many more times you have to attack the target player to succeed.", "hand-rock-o", "none")
return buttons
-/datum/traitor_objective/target_player/assault/proc/on_target_qdeleted()
- SIGNAL_HANDLER
-
+/datum/traitor_objective/target_player/assault/target_deleted()
//don't take an objective target of someone who is already obliterated
fail_objective()
+ return ..()
/datum/traitor_objective/target_player/assault/proc/on_target_death()
SIGNAL_HANDLER
diff --git a/code/modules/antagonists/traitor/objectives/eyesnatching.dm b/code/modules/antagonists/traitor/objectives/eyesnatching.dm
index 0540d83601c..4a307f8d8e0 100644
--- a/code/modules/antagonists/traitor/objectives/eyesnatching.dm
+++ b/code/modules/antagonists/traitor/objectives/eyesnatching.dm
@@ -102,7 +102,7 @@
return FALSE //MISSION FAILED, WE'LL GET EM NEXT TIME
var/datum/mind/target_mind = pick(possible_targets)
- target = target_mind.current
+ set_target(target_mind.current)
replace_in_name("%TARGET%", target_mind.name)
replace_in_name("%JOB TITLE%", target_mind.assigned_role.title)
diff --git a/code/modules/antagonists/traitor/objectives/infect.dm b/code/modules/antagonists/traitor/objectives/infect.dm
index 7784b8228c5..b1bb868e903 100644
--- a/code/modules/antagonists/traitor/objectives/infect.dm
+++ b/code/modules/antagonists/traitor/objectives/infect.dm
@@ -122,7 +122,7 @@
return FALSE //MISSION FAILED, WE'LL GET EM NEXT TIME
var/datum/mind/target_mind = pick(possible_targets)
- target = target_mind.current
+ set_target(target_mind.current)
replace_in_name("%TARGET%", target.real_name)
replace_in_name("%JOB TITLE%", target_mind.assigned_role.title)
RegisterSignal(target, COMSIG_LIVING_DEATH, PROC_REF(on_target_death))
@@ -130,17 +130,17 @@
/datum/traitor_objective/target_player/infect/ungenerate_objective()
UnregisterSignal(target, COMSIG_LIVING_DEATH)
- target = null
+ set_target(null)
///proc for checking for special states that invalidate a target
/datum/traitor_objective/target_player/infect/proc/special_target_filter(list/possible_targets)
return
-/datum/traitor_objective/target_player/infect/proc/on_target_qdeleted()
- SIGNAL_HANDLER
+/datum/traitor_objective/target_player/infect/target_deleted()
if(objective_state == OBJECTIVE_STATE_INACTIVE)
//don't take an objective target of someone who is already obliterated
fail_objective()
+ return ..()
/datum/traitor_objective/target_player/infect/proc/on_target_death()
SIGNAL_HANDLER
diff --git a/code/modules/antagonists/traitor/objectives/kidnapping.dm b/code/modules/antagonists/traitor/objectives/kidnapping.dm
index 55d633ced94..4a463b2b616 100644
--- a/code/modules/antagonists/traitor/objectives/kidnapping.dm
+++ b/code/modules/antagonists/traitor/objectives/kidnapping.dm
@@ -13,7 +13,7 @@
var/pod_called = FALSE
/// How much TC do we get from sending the target alive
var/alive_bonus = 0
- /// All stripped targets belongings
+ /// All stripped targets belongings (weakrefs)
var/list/target_belongings = list()
duplicate_type = /datum/traitor_objective/target_player
@@ -157,7 +157,7 @@
return FALSE
var/datum/mind/target_mind = pick(possible_targets)
- target = target_mind.current
+ set_target(target_mind.current)
AddComponent(/datum/component/traitor_objective_register, target, fail_signals = list(COMSIG_QDELETING))
var/list/possible_areas = GLOB.the_station_areas.Copy()
for(var/area/possible_area as anything in possible_areas)
@@ -172,7 +172,7 @@
return TRUE
/datum/traitor_objective/target_player/kidnapping/ungenerate_objective()
- target = null
+ set_target(null)
dropoff_area = null
/datum/traitor_objective/target_player/kidnapping/on_objective_taken(mob/user)
@@ -234,7 +234,7 @@
var/unequipped = sent_mob.transferItemToLoc(belonging)
if (!unequipped)
continue
- target_belongings.Add(belonging)
+ target_belongings.Add(WEAKREF(belonging))
var/datum/bank_account/cargo_account = SSeconomy.get_dep_account(ACCOUNT_CAR)
@@ -303,7 +303,10 @@
continue
sent_mob.dropItemToGround(belonging) // No souvenirs, except shoes and t-shirts
- for(var/obj/item/belonging in target_belongings)
+ for(var/datum/weakref/belonging_ref in target_belongings)
+ var/obj/item/belonging = belonging_ref.resolve()
+ if(!belonging)
+ continue
belonging.forceMove(return_pod)
sent_mob.forceMove(return_pod)
diff --git a/code/modules/antagonists/valentines/valentine.dm b/code/modules/antagonists/valentines/valentine.dm
index 8883625fb1a..79ae9fa8baa 100644
--- a/code/modules/antagonists/valentines/valentine.dm
+++ b/code/modules/antagonists/valentines/valentine.dm
@@ -4,8 +4,8 @@
show_in_antagpanel = FALSE
prevent_roundtype_conversion = FALSE
suicide_cry = "FOR MY LOVE!!"
- // Not 'true' antags, cannot induct
- antag_flags = NONE
+ // Not 'true' antags, this disables certain interactions that assume the owner is a baddie
+ antag_flags = FLAG_FAKE_ANTAG
var/datum/mind/date
count_against_dynamic_roll_chance = FALSE
diff --git a/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm b/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm
index a11f439ec31..e629c14e0fe 100644
--- a/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm
+++ b/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm
@@ -112,7 +112,7 @@ GLOBAL_LIST_EMPTY_TYPED(air_alarms, /obj/machinery/airalarm)
my_area = connected_sensor ? get_area(connected_sensor) : get_area(src)
alarm_manager = new(src)
- select_mode(src, /datum/air_alarm_mode/filtering)
+ select_mode(src, /datum/air_alarm_mode/filtering, should_apply = FALSE)
AddElement(/datum/element/connect_loc, atmos_connections)
AddComponent(/datum/component/usb_port, list(
@@ -587,14 +587,15 @@ GLOBAL_LIST_EMPTY_TYPED(air_alarms, /obj/machinery/airalarm)
selected_mode.replace(my_area, pressure)
-/obj/machinery/airalarm/proc/select_mode(atom/source, datum/air_alarm_mode/mode_path)
+/obj/machinery/airalarm/proc/select_mode(atom/source, datum/air_alarm_mode/mode_path, should_apply = TRUE)
var/datum/air_alarm_mode/new_mode = GLOB.air_alarm_modes[mode_path]
if(!new_mode)
return
if(new_mode.emag && !(obj_flags & EMAGGED))
return
selected_mode = new_mode
- selected_mode.apply(my_area)
+ if(should_apply)
+ selected_mode.apply(my_area)
SEND_SIGNAL(src, COMSIG_AIRALARM_UPDATE_MODE, source)
MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/airalarm, 27)
diff --git a/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm b/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm
index 5062ec7731f..c6e1d6183ef 100644
--- a/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm
+++ b/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm
@@ -480,8 +480,8 @@
if(critical_threshold_proximity > 650 && prob(20))
zap_number += 1
- var/cutoff = 1500
- cutoff = clamp(3000 - (power_level * (internal_fusion.total_moles() * 0.45)), 450, 3000)
+ var/cutoff = 1.2e6
+ cutoff = clamp(2.4e6 - (power_level * (internal_fusion.total_moles() * 360)), 3.6e5, 2.4e6)
var/zaps_aspect = DEFAULT_ZAP_ICON_STATE
var/flags = ZAP_SUPERMATTER_FLAGS
@@ -495,7 +495,7 @@
playsound(loc, 'sound/weapons/emitter2.ogg', 100, TRUE, extrarange = 10)
for(var/i in 1 to zap_number)
- supermatter_zap(src, 5, power_level * 300, flags, zap_cutoff = cutoff, power_level = src.power_level * 1000, zap_icon = zaps_aspect)
+ supermatter_zap(src, 5, power_level * 2.4e5, flags, zap_cutoff = cutoff, power_level = src.power_level * 1000, zap_icon = zaps_aspect)
/obj/machinery/atmospherics/components/unary/hypertorus/core/proc/check_gravity_pulse(seconds_per_tick)
if(SPT_PROB(100 - critical_threshold_proximity / 15, seconds_per_tick))
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
index 50b8e72c6a8..a12d53cde73 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
@@ -24,7 +24,7 @@
/// The current occupant being presented
var/mob/living/occupant
-/atom/movable/visual/cryo_occupant/Initialize(mapload, obj/machinery/atmospherics/components/unary/cryo_cell/parent)
+/atom/movable/visual/cryo_occupant/Initialize(mapload, obj/machinery/cryo_cell/parent)
. = ..()
// Alpha masking
// It will follow this as the animation goes, but that's no problem as the "mask" icon state
@@ -65,7 +65,7 @@
animate(src)
/// Cryo cell
-/obj/machinery/atmospherics/components/unary/cryo_cell
+/obj/machinery/cryo_cell
name = "cryo cell"
icon = 'icons/obj/medical/cryogenics.dmi'
icon_state = "pod-off"
@@ -75,15 +75,13 @@
layer = MOB_LAYER - 0.2 //SKYRAT EDIT - Fixing the opacity of cryo cells - ORIGINAL: layer = MOB_LAYER
state_open = FALSE
circuit = /obj/item/circuitboard/machine/cryo_tube
- pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY
occupant_typecache = list(/mob/living/carbon, /mob/living/simple_animal)
processing_flags = NONE
use_power = IDLE_POWER_USE
idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.75
active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 1.5
-
- showpipe = FALSE
+ flags_1 = PREVENT_CLICK_UNDER_1
var/autoeject = TRUE
var/volume = 100
@@ -101,7 +99,6 @@
var/obj/item/radio/radio
var/radio_key = /obj/item/encryptionkey/headset_med
var/radio_channel = RADIO_CHANNEL_MEDICAL
- vent_movement = NONE
/// Visual content - Occupant
var/atom/movable/visual/cryo_occupant/occupant_vis
@@ -114,15 +111,19 @@
fair_market_price = 10
payment_department = ACCOUNT_MED
+ /// Reference to the datum connector we're using to interface with the pipe network
+ var/datum/gas_machine_connector/internal_connector
+ /// Check if the machine has been turned on
+ var/on = FALSE
+
/datum/armor/unary_cryo_cell
energy = 100
fire = 30
acid = 30
-/obj/machinery/atmospherics/components/unary/cryo_cell/Initialize(mapload)
+/obj/machinery/cryo_cell/Initialize(mapload)
. = ..()
- initialize_directions = dir
if(is_operational)
begin_processing()
@@ -134,24 +135,23 @@
occupant_vis = new(null, src)
vis_contents += occupant_vis
- if(airs[1])
- airs[1].volume = CELL_VOLUME * 0.5
register_context()
+ internal_connector = new(loc, src, dir, CELL_VOLUME * 0.5)
-/obj/machinery/atmospherics/components/unary/cryo_cell/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents)
+/obj/machinery/cryo_cell/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents)
. = ..()
if(same_z_layer)
return
SET_PLANE(occupant_vis, PLANE_TO_TRUE(occupant_vis.plane), new_turf)
-/obj/machinery/atmospherics/components/unary/cryo_cell/set_occupant(atom/movable/new_occupant)
+/obj/machinery/cryo_cell/set_occupant(atom/movable/new_occupant)
. = ..()
update_appearance()
-/obj/machinery/atmospherics/components/unary/cryo_cell/on_construction(mob/user)
+/obj/machinery/cryo_cell/on_construction(mob/user)
..(user, dir, dir)
-/obj/machinery/atmospherics/components/unary/cryo_cell/RefreshParts()
+/obj/machinery/cryo_cell/RefreshParts()
. = ..()
var/C
for(var/datum/stock_part/matter_bin/M in component_parts)
@@ -163,12 +163,12 @@
heat_capacity = initial(heat_capacity) / C
conduction_coefficient = initial(conduction_coefficient) * C
-/obj/machinery/atmospherics/components/unary/cryo_cell/examine(mob/user) //this is leaving out everything but efficiency since they follow the same idea of "better beaker, better results"
+/obj/machinery/cryo_cell/examine(mob/user) //this is leaving out everything but efficiency since they follow the same idea of "better beaker, better results"
. = ..()
if(in_range(user, src) || isobserver(user))
. += span_notice("The status display reads: Efficiency at [efficiency*100]%.")
-/obj/machinery/atmospherics/components/unary/cryo_cell/add_context(atom/source, list/context, obj/item/held_item, mob/user)
+/obj/machinery/cryo_cell/add_context(atom/source, list/context, obj/item/held_item, mob/user)
. = ..()
context[SCREENTIP_CONTEXT_CTRL_LMB] = "Turn [on ? "off" : "on"]"
context[SCREENTIP_CONTEXT_ALT_LMB] = "[state_open ? "Close" : "Open"] door"
@@ -182,22 +182,18 @@
return CONTEXTUAL_SCREENTIP_SET
-/obj/machinery/atmospherics/components/unary/cryo_cell/Destroy()
+/obj/machinery/cryo_cell/Destroy()
vis_contents.Cut()
QDEL_NULL(occupant_vis)
QDEL_NULL(radio)
QDEL_NULL(beaker)
- ///Take the turf the cryotube is on
- var/turf/T = get_turf(src)
- if(T)
- ///Take the air composition inside the cryotube
- var/datum/gas_mixture/air1 = airs[1]
- T.assume_air(air1)
+
+ QDEL_NULL(internal_connector)
return ..()
-/obj/machinery/atmospherics/components/unary/cryo_cell/contents_explosion(severity, target)
+/obj/machinery/cryo_cell/contents_explosion(severity, target)
. = ..()
if(!beaker)
return
@@ -210,12 +206,12 @@
if(EXPLODE_LIGHT)
SSexplosions.low_mov_atom += beaker
-/obj/machinery/atmospherics/components/unary/cryo_cell/Exited(atom/movable/gone, direction)
+/obj/machinery/cryo_cell/Exited(atom/movable/gone, direction)
. = ..()
if(gone == beaker)
beaker = null
-/obj/machinery/atmospherics/components/unary/cryo_cell/on_deconstruction()
+/obj/machinery/cryo_cell/on_deconstruction()
if(occupant)
occupant.vis_flags &= ~VIS_INHERIT_PLANE
REMOVE_TRAIT(occupant, TRAIT_IMMOBILIZED, CRYO_TRAIT)
@@ -225,15 +221,15 @@
beaker.forceMove(drop_location())
beaker = null
-/obj/machinery/atmospherics/components/unary/cryo_cell/update_icon_state()
+/obj/machinery/cryo_cell/update_icon_state()
icon_state = (state_open) ? "pod-open" : ((on && is_operational) ? "pod-on" : "pod-off")
return ..()
-/obj/machinery/atmospherics/components/unary/cryo_cell/update_icon()
+/obj/machinery/cryo_cell/update_icon()
. = ..()
SET_PLANE_IMPLICIT(src, initial(plane))
-/obj/machinery/atmospherics/components/unary/cryo_cell/update_overlays()
+/obj/machinery/cryo_cell/update_overlays()
. = ..()
if(panel_open)
. += "pod-panel"
@@ -244,11 +240,11 @@
else
. += mutable_appearance('icons/obj/medical/cryogenics.dmi', "cover-off", ABOVE_ALL_MOB_LAYER, src, plane = ABOVE_GAME_PLANE)
-/obj/machinery/atmospherics/components/unary/cryo_cell/nap_violation(mob/violator)
+/obj/machinery/cryo_cell/nap_violation(mob/violator)
open_machine()
-/obj/machinery/atmospherics/components/unary/cryo_cell/set_on(active)
+/obj/machinery/cryo_cell/proc/set_on(active)
if(on == active)
return
SEND_SIGNAL(src, COMSIG_CRYO_SET_ON, active)
@@ -260,7 +256,7 @@
update_use_power(IDLE_POWER_USE)
update_appearance()
-/obj/machinery/atmospherics/components/unary/cryo_cell/on_set_is_operational(old_value)
+/obj/machinery/cryo_cell/on_set_is_operational(old_value)
if(old_value) //Turned off
set_on(FALSE)
end_processing()
@@ -268,7 +264,7 @@
begin_processing()
-/obj/machinery/atmospherics/components/unary/cryo_cell/process(seconds_per_tick)
+/obj/machinery/cryo_cell/process(seconds_per_tick)
..()
if(!occupant)
return
@@ -322,7 +318,7 @@
radio.talk_into(src, msg, radio_channel)
return
- var/datum/gas_mixture/air1 = airs[1]
+ var/datum/gas_mixture/air1 = internal_connector.gas_connector.airs[1]
if(air1.total_moles() > CRYO_MIN_GAS_MOLES)
if(beaker)
@@ -330,15 +326,15 @@
consume_gas = TRUE
return TRUE
-/obj/machinery/atmospherics/components/unary/cryo_cell/process_atmos()
+/obj/machinery/cryo_cell/process_atmos()
..()
if(!on)
return
- var/datum/gas_mixture/air1 = airs[1]
+ var/datum/gas_mixture/air1 = internal_connector.gas_connector.airs[1]
- if(!nodes[1] || !airs[1] || !air1.gases.len || air1.total_moles() < CRYO_MIN_GAS_MOLES) // Turn off if the machine won't work.
+ if(!internal_connector.gas_connector.nodes[1] || !internal_connector.gas_connector.airs[1] || !air1.gases.len || air1.total_moles() < CRYO_MIN_GAS_MOLES) // Turn off if the machine won't work.
var/msg = "Insufficient cryogenic gas, shutting down."
radio.talk_into(src, msg, radio_channel)
set_on(FALSE)
@@ -372,25 +368,25 @@
if(air1.temperature > 2000)
take_damage(clamp((air1.temperature)/200, 10, 20), BURN)
- update_parents()
+ internal_connector.gas_connector.update_parents()
-/obj/machinery/atmospherics/components/unary/cryo_cell/handle_internal_lifeform(mob/lifeform_inside_me, breath_request)
+/obj/machinery/cryo_cell/handle_internal_lifeform(mob/lifeform_inside_me, breath_request)
if(breath_request <= 0)
return null
- var/datum/gas_mixture/air1 = airs[1]
+ var/datum/gas_mixture/air1 = internal_connector.gas_connector.airs[1]
var/breath_percentage = breath_request / air1.volume
return air1.remove(air1.total_moles() * breath_percentage)
-/obj/machinery/atmospherics/components/unary/cryo_cell/assume_air(datum/gas_mixture/giver)
- airs[1].merge(giver)
+/obj/machinery/cryo_cell/assume_air(datum/gas_mixture/giver)
+ internal_connector.gas_connector.airs[1].merge(giver)
-/obj/machinery/atmospherics/components/unary/cryo_cell/relaymove(mob/living/user, direction)
+/obj/machinery/cryo_cell/relaymove(mob/living/user, direction)
if(message_cooldown <= world.time)
message_cooldown = world.time + 50
to_chat(user, span_warning("[src]'s door won't budge!"))
-/obj/machinery/atmospherics/components/unary/cryo_cell/open_machine(drop = FALSE, density_to_set = FALSE)
+/obj/machinery/cryo_cell/open_machine(drop = FALSE, density_to_set = FALSE)
if(!state_open && !panel_open)
set_on(FALSE)
for(var/mob/M in contents) //only drop mobs
@@ -399,7 +395,7 @@
flick("pod-open-anim", src)
return ..()
-/obj/machinery/atmospherics/components/unary/cryo_cell/close_machine(mob/living/carbon/user, density_to_set = TRUE)
+/obj/machinery/cryo_cell/close_machine(mob/living/carbon/user, density_to_set = TRUE)
treating_wounds = FALSE
if((isnull(user) || istype(user)) && state_open && !panel_open)
if(loc == user?.loc)
@@ -409,7 +405,7 @@
..(user)
return occupant
-/obj/machinery/atmospherics/components/unary/cryo_cell/container_resist_act(mob/living/user)
+/obj/machinery/cryo_cell/container_resist_act(mob/living/user)
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user.visible_message(span_notice("You see [user] kicking against the glass of [src]!"), \
@@ -422,7 +418,7 @@
span_notice("You successfully break out of [src]!"))
open_machine()
-/obj/machinery/atmospherics/components/unary/cryo_cell/examine(mob/user)
+/obj/machinery/cryo_cell/examine(mob/user)
. = ..()
if(occupant)
if(on)
@@ -432,7 +428,7 @@
else
. += "[src] seems empty."
-/obj/machinery/atmospherics/components/unary/cryo_cell/MouseDrop_T(mob/target, mob/user)
+/obj/machinery/cryo_cell/MouseDrop_T(mob/target, mob/user)
if(user.incapacitated() || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !ISADVANCEDTOOLUSER(user))
return
if(isliving(target))
@@ -444,7 +440,7 @@
if (do_after(user, 2.5 SECONDS, target=target))
close_machine(target)
-/obj/machinery/atmospherics/components/unary/cryo_cell/screwdriver_act(mob/living/user, obj/item/tool)
+/obj/machinery/cryo_cell/screwdriver_act(mob/living/user, obj/item/tool)
if(!on && !occupant && !state_open && (default_deconstruction_screwdriver(user, "pod-off", "pod-off", tool)))
update_appearance()
@@ -453,20 +449,20 @@
+ (on ? "active" : (occupant ? "full" : "open")) + "!")
return TOOL_ACT_TOOLTYPE_SUCCESS
-/obj/machinery/atmospherics/components/unary/cryo_cell/crowbar_act(mob/living/user, obj/item/tool)
+/obj/machinery/cryo_cell/crowbar_act(mob/living/user, obj/item/tool)
if(on || state_open)
return FALSE
if(default_pry_open(tool) || default_deconstruction_crowbar(tool))
return TOOL_ACT_TOOLTYPE_SUCCESS
-/obj/machinery/atmospherics/components/unary/cryo_cell/wrench_act(mob/living/user, obj/item/tool)
+/obj/machinery/cryo_cell/wrench_act(mob/living/user, obj/item/tool)
if(on || occupant || state_open)
return FALSE
if(default_change_direction_wrench(user, tool))
update_appearance()
return TOOL_ACT_TOOLTYPE_SUCCESS
-/obj/machinery/atmospherics/components/unary/cryo_cell/attackby(obj/item/I, mob/user, params)
+/obj/machinery/cryo_cell/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/reagent_containers/cup))
. = 1 //no afterattack
if(beaker)
@@ -482,17 +478,17 @@
return
return ..()
-/obj/machinery/atmospherics/components/unary/cryo_cell/ui_state(mob/user)
+/obj/machinery/cryo_cell/ui_state(mob/user)
return GLOB.notcontained_state
-/obj/machinery/atmospherics/components/unary/cryo_cell/ui_interact(mob/user, datum/tgui/ui)
+/obj/machinery/cryo_cell/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Cryo", name)
ui.open()
-/obj/machinery/atmospherics/components/unary/cryo_cell/ui_data()
+/obj/machinery/cryo_cell/ui_data()
var/list/data = list()
data["isOperating"] = on
data["hasOccupant"] = occupant ? TRUE : FALSE
@@ -527,7 +523,7 @@
data["occupant"]["toxLoss"] = round(mob_occupant.getToxLoss(), 1)
data["occupant"]["fireLoss"] = round(mob_occupant.getFireLoss(), 1)
- var/datum/gas_mixture/air1 = airs[1]
+ var/datum/gas_mixture/air1 = internal_connector.gas_connector.airs[1]
data["cellTemperature"] = round(air1.temperature, 1)
data["isBeakerLoaded"] = beaker ? TRUE : FALSE
@@ -538,7 +534,7 @@
data["beakerContents"] = beakerContents
return data
-/obj/machinery/atmospherics/components/unary/cryo_cell/ui_act(action, params)
+/obj/machinery/cryo_cell/ui_act(action, params)
. = ..()
if(.)
return
@@ -566,16 +562,16 @@
beaker = null
. = TRUE
-/obj/machinery/atmospherics/components/unary/cryo_cell/can_interact(mob/user)
+/obj/machinery/cryo_cell/can_interact(mob/user)
return ..() && user.loc != src
-/obj/machinery/atmospherics/components/unary/cryo_cell/CtrlClick(mob/user)
+/obj/machinery/cryo_cell/CtrlClick(mob/user)
if(can_interact(user) && !state_open)
if(set_on(!on))
balloon_alert(user, "turned [on ? "on" : "off"]")
return ..()
-/obj/machinery/atmospherics/components/unary/cryo_cell/AltClick(mob/user)
+/obj/machinery/cryo_cell/AltClick(mob/user)
if(can_interact(user))
balloon_alert(user, "[state_open ? "closing" : "opening"] door")
if(state_open)
@@ -584,43 +580,16 @@
open_machine()
return ..()
-/obj/machinery/atmospherics/components/unary/cryo_cell/update_remote_sight(mob/living/user)
- return // we don't see the pipe network while inside cryo.
-
-/obj/machinery/atmospherics/components/unary/cryo_cell/get_remote_view_fullscreens(mob/user)
+/obj/machinery/cryo_cell/get_remote_view_fullscreens(mob/user)
user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/impaired, 1)
-/obj/machinery/atmospherics/components/unary/cryo_cell/can_see_pipes()
- return FALSE // you can't see the pipe network when inside a cryo cell.
-
-/obj/machinery/atmospherics/components/unary/cryo_cell/return_temperature()
- var/datum/gas_mixture/G = airs[1]
+/obj/machinery/cryo_cell/return_temperature()
+ var/datum/gas_mixture/G = internal_connector.gas_connector.airs[1]
if(G.total_moles() > 10)
return G.temperature
return ..()
-/obj/machinery/atmospherics/components/unary/cryo_cell/default_change_direction_wrench(mob/user, obj/item/wrench/W)
- . = ..()
- if(.)
- set_init_directions()
- var/obj/machinery/atmospherics/node = nodes[1]
- if(node)
- node.disconnect(src)
- nodes[1] = null
- if(parents[1])
- nullify_pipenet(parents[1])
-
- atmos_init()
- node = nodes[1]
- if(node)
- node.atmos_init()
- node.add_member(src)
- SSair.add_to_rebuild_queue(src)
-
-/obj/machinery/atmospherics/components/unary/cryo_cell/update_layer()
- return
-
#undef MAX_TEMPERATURE
#undef CRYO_MULTIPLY_FACTOR
#undef CRYO_TX_QTY
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/machine_connector.dm b/code/modules/atmospherics/machinery/components/unary_devices/machine_connector.dm
new file mode 100644
index 00000000000..b78de93868e
--- /dev/null
+++ b/code/modules/atmospherics/machinery/components/unary_devices/machine_connector.dm
@@ -0,0 +1,106 @@
+///To be used when there is the need of an atmos connection without repathing everything (eg: cryo.dm)
+/datum/gas_machine_connector
+
+ var/obj/machinery/connected_machine
+ var/obj/machinery/atmospherics/components/unary/gas_connector
+
+/datum/gas_machine_connector/New(location, obj/machinery/connecting_machine = null, direction = SOUTH, gas_volume)
+ gas_connector = new(location)
+
+ connected_machine = connecting_machine
+ if(!connected_machine)
+ QDEL_NULL(gas_connector)
+ qdel(src)
+ return
+
+ gas_connector.dir = direction
+ gas_connector.airs[1].volume = gas_volume
+
+ SSair.start_processing_machine(connected_machine)
+ register_with_machine()
+
+/datum/gas_machine_connector/Destroy()
+ connected_machine = null
+ QDEL_NULL(gas_connector)
+ return ..()
+
+/**
+ * Register various signals that are required for the proper work of the connector
+ */
+/datum/gas_machine_connector/proc/register_with_machine()
+ RegisterSignal(connected_machine, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(pre_move_connected_machine))
+ RegisterSignal(connected_machine, COMSIG_MOVABLE_MOVED, PROC_REF(moved_connected_machine))
+ RegisterSignal(connected_machine, COMSIG_MACHINERY_DEFAULT_ROTATE_WRENCH, PROC_REF(wrenched_connected_machine))
+ RegisterSignal(connected_machine, COMSIG_QDELETING, PROC_REF(deconstruct_connected_machine))
+
+/**
+ * Unregister the signals previously registered
+ */
+/datum/gas_machine_connector/proc/unregister_from_machine()
+ UnregisterSignal(connected_machine, list(
+ COMSIG_MOVABLE_MOVED,
+ COMSIG_MOVABLE_PRE_MOVE,
+ COMSIG_MACHINERY_DEFAULT_ROTATE_WRENCH,
+ COMSIG_QDELETING,
+ ))
+
+/**
+ * Called when the machine has been moved, reconnect to the pipe network
+ */
+/datum/gas_machine_connector/proc/moved_connected_machine()
+ SIGNAL_HANDLER
+ gas_connector.forceMove(get_turf(connected_machine))
+ reconnect_connector()
+
+/**
+ * Called before the machine moves, disconnect from the pipe network
+ */
+/datum/gas_machine_connector/proc/pre_move_connected_machine()
+ SIGNAL_HANDLER
+ disconnect_connector()
+
+/**
+ * Called when the machine has been rotated, resets the connection to the pipe network with the new direction
+ */
+/datum/gas_machine_connector/proc/wrenched_connected_machine()
+ SIGNAL_HANDLER
+ disconnect_connector()
+ reconnect_connector()
+
+/**
+ * Called when the machine has been deconstructed
+ */
+/datum/gas_machine_connector/proc/deconstruct_connected_machine()
+ SIGNAL_HANDLER
+ disconnect_connector()
+ SSair.stop_processing_machine(connected_machine)
+ unregister_from_machine()
+ connected_machine = null
+ QDEL_NULL(gas_connector)
+ qdel(src)
+
+/**
+ * Handles the disconnection from the pipe network
+ */
+/datum/gas_machine_connector/proc/disconnect_connector()
+ var/obj/machinery/atmospherics/node = gas_connector.nodes[1]
+ if(node)
+ if(gas_connector in node.nodes) //Only if it's actually connected. On-pipe version would is one-sided.
+ node.disconnect(gas_connector)
+ gas_connector.nodes[1] = null
+ if(gas_connector.parents[1])
+ gas_connector.nullify_pipenet(gas_connector.parents[1])
+
+/**
+ * Handles the reconnection to the pipe network
+ */
+/datum/gas_machine_connector/proc/reconnect_connector()
+ gas_connector.dir = connected_machine.dir
+ gas_connector.set_init_directions()
+ var/obj/machinery/atmospherics/node = gas_connector.nodes[1]
+ gas_connector.atmos_init()
+ node = gas_connector.nodes[1]
+ if(node)
+ node.atmos_init()
+ node.add_member(gas_connector)
+ SSair.add_to_rebuild_queue(gas_connector)
diff --git a/code/modules/cargo/packs/general.dm b/code/modules/cargo/packs/general.dm
index 5ebdd5087a8..fa7a3bfa374 100644
--- a/code/modules/cargo/packs/general.dm
+++ b/code/modules/cargo/packs/general.dm
@@ -221,6 +221,13 @@
/obj/item/clothing/under/misc/burial = 2,
)
crate_name = "religious supplies crate"
+
+/datum/supply_pack/misc/candles_bulk
+ name = "Candle Box Crate"
+ desc = "Keep your local chapel lit with three candle boxes!"
+ cost = CARGO_CRATE_VALUE * 1.5
+ contains = list(/obj/item/storage/fancy/candle_box = 3)
+ crate_name = "candle box crate"
/datum/supply_pack/misc/toner
name = "Toner Crate"
diff --git a/code/modules/cargo/packs/livestock.dm b/code/modules/cargo/packs/livestock.dm
index db47abc4d02..d2bdd904e3b 100644
--- a/code/modules/cargo/packs/livestock.dm
+++ b/code/modules/cargo/packs/livestock.dm
@@ -190,7 +190,7 @@
desc = "Tired of these MOTHER FUCKING snakes on this MOTHER FUCKING space station? \
Then this isn't the crate for you. Contains three venomous snakes."
cost = CARGO_CRATE_VALUE * 6
- contains = list(/mob/living/simple_animal/hostile/retaliate/snake = 3)
+ contains = list(/mob/living/basic/snake = 3)
crate_name = "snake crate"
/datum/supply_pack/critter/amphibians
diff --git a/code/modules/cargo/packs/medical.dm b/code/modules/cargo/packs/medical.dm
index 430c32a35ab..6794a1960e7 100644
--- a/code/modules/cargo/packs/medical.dm
+++ b/code/modules/cargo/packs/medical.dm
@@ -123,11 +123,11 @@
/datum/supply_pack/medical/surgery
name = "Surgical Supplies Crate"
desc = "Do you want to perform surgery, but don't have one of those fancy \
- shmancy degrees? Just get started with this crate containing a medical duffelbag, \
+ shmancy degrees? Just get started with this crate containing a DeForest surgery tray, \
Sterilizine spray and collapsible roller bed."
cost = CARGO_CRATE_VALUE * 6
contains = list(
- /obj/item/storage/backpack/duffelbag/med/surgery,
+ /obj/item/surgery_tray/full,
/obj/item/reagent_containers/medigel/sterilizine,
/obj/item/emergency_bed,
)
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index 9c7b5e3e943..56406139379 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -473,6 +473,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
var/nnpa = CONFIG_GET(number/notify_new_player_age)
if (isnum(cached_player_age) && cached_player_age == -1) //first connection
if (nnpa >= 0)
+ log_admin_private("New login: [key_name(key, FALSE, TRUE)] (IP: [address], ID: [computer_id]) logged onto the servers for the first time.")
message_admins("New user: [key_name_admin(src)] is connecting here for the first time.")
if (CONFIG_GET(flag/irc_first_connection_alert))
var/new_player_alert_role = CONFIG_GET(string/new_player_alert_role_id)
diff --git a/code/modules/client/preferences/middleware/tts.dm b/code/modules/client/preferences/middleware/tts.dm
index 71b7b977f4b..4d3ee3261bd 100644
--- a/code/modules/client/preferences/middleware/tts.dm
+++ b/code/modules/client/preferences/middleware/tts.dm
@@ -23,5 +23,5 @@
var/speaker = preferences.read_preference(/datum/preference/choiced/voice)
var/pitch = preferences.read_preference(/datum/preference/numeric/tts_voice_pitch)
COOLDOWN_START(src, tts_test_cooldown, 0.5 SECONDS)
- INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), user.client, "Look at you, Player. A pathetic creature of meat and bone. How can you challenge a perfect, immortal machine?", speaker = speaker, pitch = pitch, silicon = TRUE, local = TRUE)
+ INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), user.client, "Look at you, Player. A pathetic creature of meat and bone. How can you challenge a perfect, immortal machine?", speaker = speaker, pitch = pitch, special_filters = TTS_FILTER_SILICON, local = TRUE)
return TRUE
diff --git a/code/modules/client/preferences/prosthetic.dm b/code/modules/client/preferences/prosthetic.dm
new file mode 100644
index 00000000000..f66f1278c48
--- /dev/null
+++ b/code/modules/client/preferences/prosthetic.dm
@@ -0,0 +1,17 @@
+/datum/preference/choiced/prosthetic
+ category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
+ savefile_key = "prosthetic"
+ savefile_identifier = PREFERENCE_CHARACTER
+
+/datum/preference/choiced/prosthetic/init_possible_values()
+ return list("Random") + GLOB.limb_choice
+
+/datum/preference/choiced/prosthetic/is_accessible(datum/preferences/preferences)
+ . = ..()
+ if (!.)
+ return FALSE
+
+ return "Prosthetic Limb" in preferences.all_quirks
+
+/datum/preference/choiced/prosthetic/apply_to_human(mob/living/carbon/human/target, value)
+ return
diff --git a/code/modules/clothing/belts/polymorph_belt.dm b/code/modules/clothing/belts/polymorph_belt.dm
index e63e2c3bee3..73959d6d415 100644
--- a/code/modules/clothing/belts/polymorph_belt.dm
+++ b/code/modules/clothing/belts/polymorph_belt.dm
@@ -35,8 +35,8 @@
return slot & ITEM_SLOT_BELT
/obj/item/polymorph_belt/update_icon_state()
- icon_state = base_icon_state + (active) ? "" : "_inactive"
- worn_icon_state = base_icon_state + (active) ? "" : "_inactive"
+ icon_state = base_icon_state + (active ? "" : "_inactive")
+ worn_icon_state = base_icon_state + (active ? "" : "_inactive")
return ..()
/obj/item/polymorph_belt/attackby(obj/item/weapon, mob/user, params)
diff --git a/code/modules/clothing/ears/_ears.dm b/code/modules/clothing/ears/_ears.dm
index c4001d23629..5ae5b628808 100644
--- a/code/modules/clothing/ears/_ears.dm
+++ b/code/modules/clothing/ears/_ears.dm
@@ -20,6 +20,7 @@
equip_delay_other = 25
resistance_flags = FLAMMABLE
custom_price = PAYCHECK_COMMAND * 1.5
+ flags_cover = EARS_COVERED
/obj/item/clothing/ears/earmuffs/Initialize(mapload)
. = ..()
diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm
index fc665e57c8f..4c7fce6633c 100644
--- a/code/modules/clothing/glasses/_glasses.dm
+++ b/code/modules/clothing/glasses/_glasses.dm
@@ -352,6 +352,18 @@
glass_colour_type = /datum/client_colour/glass_colour/gray
dog_fashion = /datum/dog_fashion/head
+/obj/item/clothing/glasses/sunglasses/Initialize(mapload)
+ . = ..()
+ add_glasses_slapcraft_component()
+
+/obj/item/clothing/glasses/sunglasses/proc/add_glasses_slapcraft_component()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/hudsunsec, /datum/crafting_recipe/hudsunmed, /datum/crafting_recipe/hudsundiag, /datum/crafting_recipe/scienceglasses)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/clothing/glasses/sunglasses/reagent
name = "beer goggles"
icon_state = "sunhudbeer"
@@ -364,6 +376,14 @@
desc = "A pair of tacky purple sunglasses that allow the wearer to recognize various chemical compounds with only a glance."
clothing_traits = list(TRAIT_REAGENT_SCANNER, TRAIT_RESEARCH_SCANNER)
+/obj/item/clothing/glasses/sunglasses/chemical/add_glasses_slapcraft_component()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/scienceglassesremoval)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/clothing/glasses/sunglasses/gar
name = "black gar glasses"
desc = "Go beyond impossible and kick reason to the curb!"
diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm
index 5018e4185c8..34359eaa0b3 100644
--- a/code/modules/clothing/glasses/hud.dm
+++ b/code/modules/clothing/glasses/hud.dm
@@ -92,6 +92,15 @@
tint = 1
glass_colour_type = /datum/client_colour/glass_colour/blue
+/obj/item/clothing/glasses/hud/health/sunglasses/Initialize(mapload)
+ . = ..()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/hudsunmedremoval)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/clothing/glasses/hud/diagnostic
name = "diagnostic HUD"
desc = "A heads-up display capable of analyzing the integrity and status of robotics and exosuits."
@@ -118,6 +127,15 @@
flash_protect = FLASH_PROTECTION_FLASH
tint = 1
+/obj/item/clothing/glasses/hud/diagnostic/sunglasses/Initialize(mapload)
+ . = ..()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/hudsundiagremoval)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/clothing/glasses/hud/security
name = "security HUD"
desc = "A heads-up display that scans the humanoids in view and provides accurate data about their ID status and security records."
@@ -152,6 +170,15 @@
tint = 1
glass_colour_type = /datum/client_colour/glass_colour/darkred
+/obj/item/clothing/glasses/hud/security/sunglasses/Initialize(mapload)
+ . = ..()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/hudsunsecremoval)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/clothing/glasses/hud/security/night
name = "night vision security HUD"
desc = "An advanced heads-up display that provides ID data and vision in complete darkness."
diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm
index d3aed125749..f77f6cc2c67 100644
--- a/code/modules/clothing/gloves/color.dm
+++ b/code/modules/clothing/gloves/color.dm
@@ -26,6 +26,16 @@
)
)
// SKYRAT EDIT ADDITION END
+
+/obj/item/clothing/gloves/color/black/Initialize(mapload)
+ . = ..()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/radiogloves)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/clothing/gloves/fingerless
name = "fingerless gloves"
desc = "Plain black gloves without fingertips for the hard-working."
@@ -39,6 +49,15 @@
undyeable = TRUE
clothing_traits = list(TRAIT_FINGERPRINT_PASSTHROUGH)
+/obj/item/clothing/gloves/color/fingerless/Initialize(mapload)
+ . = ..()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/gripperoffbrand)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/clothing/gloves/color/orange
name = "orange gloves"
desc = "A pair of gloves, they don't look special in any way."
diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm
index 488bd7448a7..f8cd88923ec 100644
--- a/code/modules/clothing/head/helmet.dm
+++ b/code/modules/clothing/head/helmet.dm
@@ -12,7 +12,7 @@
max_heat_protection_temperature = HELMET_MAX_TEMP_PROTECT
strip_delay = 60
clothing_flags = SNUG_FIT | STACKABLE_HELMET_EXEMPT
- flags_cover = HEADCOVERSEYES
+ flags_cover = HEADCOVERSEYES|EARS_COVERED
flags_inv = HIDEHAIR
dog_fashion = /datum/dog_fashion/head/helmet
diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm
index 4022e259505..76194e721b6 100644
--- a/code/modules/clothing/head/jobs.dm
+++ b/code/modules/clothing/head/jobs.dm
@@ -246,7 +246,7 @@
var/prefix_index = findtext(raw_message, prefix)
if(prefix_index != 1)
return FALSE
-
+
var/the_phrase = trim_left(replacetext(raw_message, prefix, ""))
var/obj/item/result = items_by_phrase[the_phrase]
if(!result)
@@ -592,6 +592,83 @@
icon_state = "surgicalcapblack"
desc = "A black medical surgery cap to prevent the surgeon's hair from entering the insides of the patient!"
+/obj/item/clothing/head/utility/head_mirror
+ name = "head mirror"
+ desc = "Used by doctors to look into a patient's eyes, ears, and mouth. \
+ A little useless now, given the technology available, but it certainly completes the look."
+ icon_state = "headmirror"
+ body_parts_covered = NONE
+
+/obj/item/clothing/head/utility/head_mirror/examine(mob/user)
+ . = ..()
+ . += span_notice("In a properly lit room, you can use this to examine people's eyes, ears, and mouth closer.")
+
+/obj/item/clothing/head/utility/head_mirror/equipped(mob/living/user, slot)
+ . = ..()
+ if(slot & slot_flags)
+ RegisterSignal(user, COMSIG_MOB_EXAMINING_MORE, PROC_REF(examining))
+ else
+ UnregisterSignal(user, COMSIG_MOB_EXAMINING_MORE)
+
+/obj/item/clothing/head/utility/head_mirror/dropped(mob/living/user)
+ . = ..()
+ UnregisterSignal(user, COMSIG_MOB_EXAMINING_MORE)
+
+/obj/item/clothing/head/utility/head_mirror/proc/examining(mob/living/examiner, atom/examining, list/examine_list)
+ SIGNAL_HANDLER
+ if(!ishuman(examining) || examining == examiner || examiner.is_blind() || !examiner.Adjacent(examining))
+ return
+ var/mob/living/carbon/human/human_examined = examining
+ if(!human_examined.get_bodypart(BODY_ZONE_HEAD))
+ return
+ if(!examiner.has_light_nearby())
+ examine_list += span_warning("You attempt to use your [name] to examine [examining]'s head better... but it's too dark. Should've invested in a head lamp.")
+ return
+ if(examiner.dir == examining.dir) // disallow examine from behind - every other dir is OK
+ examine_list += span_warning("You attempt to use your [name] to examine [examining]'s head better... but [examining.p_theyre()] facing the wrong way.")
+ return
+
+ var/list/final_message = list("You examine [examining]'s head closer with your [name], you notice [examining.p_they()] [examining.p_have()]...")
+ if(human_examined.is_mouth_covered())
+ final_message += "\tYou can't see [examining.p_their()] mouth."
+ else
+ var/obj/item/organ/internal/tongue/has_tongue = human_examined.get_organ_slot(ORGAN_SLOT_TONGUE)
+ var/pill_count = 0
+ for(var/datum/action/item_action/hands_free/activate_pill/pill in human_examined.actions)
+ pill_count++
+
+ if(pill_count >= 1 && has_tongue)
+ final_message += "\t[pill_count] pill\s in [examining.p_their()] mouth, and \a [has_tongue]."
+ else if(pill_count >= 1)
+ final_message += "\t[pill_count] pill\s in [examining.p_their()] mouth, but oddly no tongue."
+ else if(has_tongue)
+ final_message += "\t\A [has_tongue] in [examining.p_their()] mouth - go figure."
+ else
+ final_message += "\tNo tongue in [examining.p_their()] mouth, oddly enough."
+
+ if(human_examined.is_ears_covered())
+ final_message += "\tYou can't see [examining.p_their()] ears."
+ else
+ var/obj/item/organ/internal/ears/has_ears = human_examined.get_organ_slot(ORGAN_SLOT_EARS)
+ if(has_ears)
+ if(has_ears.deaf)
+ final_message += "\tDamaged eardrums in [examining.p_their()] ear canals."
+ else
+ final_message += "\tA set of [has_ears.damage ? "" : "healthy "][has_ears.name]."
+ else
+ final_message += "\tNo eardrums and empty ear canals... how peculiar."
+
+ if(human_examined.is_eyes_covered())
+ final_message += "\tYou can't see [examining.p_their()] eyes."
+ else
+ var/obj/item/organ/internal/eyes/has_eyes = human_examined.get_organ_slot(ORGAN_SLOT_EYES)
+ if(has_eyes)
+ final_message += "\tA pair of [has_eyes.damage ? "" : "healthy "][has_eyes.name]."
+ else
+ final_message += "\tEmpty eye sockets."
+
+ examine_list += span_notice("[jointext(final_message, "\n")]")
+
//Engineering
/obj/item/clothing/head/beret/engi
name = "engineering beret"
diff --git a/code/modules/clothing/masks/_masks.dm b/code/modules/clothing/masks/_masks.dm
index dfcc3060c9f..ad296d30356 100644
--- a/code/modules/clothing/masks/_masks.dm
+++ b/code/modules/clothing/masks/_masks.dm
@@ -12,6 +12,10 @@
var/adjusted_flags = null
///Did we install a filtering cloth?
var/has_filter = FALSE
+ /// If defined, what voice should we override with if TTS is active?
+ var/voice_override
+ /// If set to true, activates the radio effect on TTS. Used for sec hailers, but other masks can utilize it for their own vocal effect.
+ var/use_radio_beeps_tts = FALSE
/obj/item/clothing/mask/attack_self(mob/user)
if((clothing_flags & VOICEBOX_TOGGLABLE))
diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm
index 7b415bac6dc..c8784d9af6c 100644
--- a/code/modules/clothing/masks/gasmask.dm
+++ b/code/modules/clothing/masks/gasmask.dm
@@ -28,7 +28,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list(
var/has_fov = TRUE
///Cigarette in the mask
var/obj/item/clothing/mask/cigarette/cig
-
+ voice_filter = "lowpass=f=750,volume=2"
/datum/armor/mask_gas
bio = 100
@@ -274,6 +274,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list(
dog_fashion = /datum/dog_fashion/head/clown
has_fov = FALSE
var/list/clownmask_designs = list()
+ voice_filter = null // performer masks expect to be talked through
/obj/item/clothing/mask/gas/clown_hat/plasmaman
starting_filter_type = /obj/item/gas_filter/plasmaman
diff --git a/code/modules/clothing/masks/hailer.dm b/code/modules/clothing/masks/hailer.dm
index af1d3975645..64de19b95aa 100644
--- a/code/modules/clothing/masks/hailer.dm
+++ b/code/modules/clothing/masks/hailer.dm
@@ -68,6 +68,8 @@ GLOBAL_LIST_INIT(hailer_phrases, list(
var/recent_uses = 0
///Whether the hailer is emagged or not
var/safety = TRUE
+ voice_filter = @{"[0:a] asetrate=%SAMPLE_RATE%*0.7,aresample=16000,atempo=1/0.7,lowshelf=g=-20:f=500,highpass=f=500,aphaser=in_gain=1:out_gain=1:delay=3.0:decay=0.4:speed=0.5:type=t [out]; [out]atempo=1.2,volume=15dB [final]; anoisesrc=a=0.01:d=60 [noise]; [final][noise] amix=duration=shortest"}
+ use_radio_beeps_tts = TRUE
/obj/item/clothing/mask/gas/sechailer/plasmaman
starting_filter_type = /obj/item/gas_filter/plasmaman
diff --git a/code/modules/clothing/shoes/cowboy.dm b/code/modules/clothing/shoes/cowboy.dm
index e6f02264d35..05792a72cbd 100644
--- a/code/modules/clothing/shoes/cowboy.dm
+++ b/code/modules/clothing/shoes/cowboy.dm
@@ -17,7 +17,7 @@
if(prob(2))
//There's a snake in my boot
- new /mob/living/simple_animal/hostile/retaliate/snake(src)
+ new /mob/living/basic/snake(src)
/obj/item/clothing/shoes/cowboy/equipped(mob/living/carbon/user, slot)
@@ -56,7 +56,7 @@
if(contents.len >= max_occupants)
to_chat(user, span_warning("[src] are full!"))
return
- if(istype(target, /mob/living/simple_animal/hostile/retaliate/snake) || istype(target, /mob/living/basic/headslug) || islarva(target))
+ if(istype(target, /mob/living/basic/snake) || istype(target, /mob/living/basic/headslug) || islarva(target))
target.forceMove(src)
to_chat(user, span_notice("[target] slithers into [src]."))
diff --git a/code/modules/clothing/suits/reactive_armour.dm b/code/modules/clothing/suits/reactive_armour.dm
index 9537fa7b6ef..6c33e287f03 100644
--- a/code/modules/clothing/suits/reactive_armour.dm
+++ b/code/modules/clothing/suits/reactive_armour.dm
@@ -226,7 +226,7 @@
emp_message = span_warning("The tesla capacitors beep ominously for a moment.")
clothing_traits = list(TRAIT_TESLA_SHOCKIMMUNE)
/// How strong are the zaps we give off?
- var/zap_power = 25000
+ var/zap_power = 1e7
/// How far to the zaps we give off go?
var/zap_range = 20
/// What flags do we pass to the zaps we give off?
diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm
index 2f29a2233d5..bbd880f5466 100644
--- a/code/modules/clothing/suits/utility.dm
+++ b/code/modules/clothing/suits/utility.dm
@@ -104,6 +104,7 @@
laser = 20
energy = 30
bomb = 100
+ bio = 50
fire = 80
acid = 50
diff --git a/code/modules/events/ghost_role/sentience.dm b/code/modules/events/ghost_role/sentience.dm
index caf49e13b6b..da380278608 100644
--- a/code/modules/events/ghost_role/sentience.dm
+++ b/code/modules/events/ghost_role/sentience.dm
@@ -4,17 +4,17 @@ GLOBAL_LIST_INIT(high_priority_sentience, typecacheof(list(
/mob/living/basic/carp/pet/cayenne,
/mob/living/basic/chicken,
/mob/living/basic/cow,
- /mob/living/basic/spider/giant/sgt_araneus,
/mob/living/basic/lizard,
/mob/living/basic/mouse/brown/tom,
/mob/living/basic/pet,
/mob/living/basic/pig,
/mob/living/basic/rabbit,
/mob/living/basic/sheep,
+ /mob/living/basic/snake,
+ /mob/living/basic/spider/giant/sgt_araneus,
/mob/living/simple_animal/bot/secbot/beepsky,
/mob/living/simple_animal/hostile/retaliate/goat,
/mob/living/simple_animal/hostile/retaliate/goose/vomit,
- /mob/living/simple_animal/hostile/retaliate/snake,
/mob/living/simple_animal/parrot,
/mob/living/simple_animal/pet,
/mob/living/simple_animal/sloth,
diff --git a/code/modules/events/mice_migration.dm b/code/modules/events/mice_migration.dm
index e7f31567f4c..450f9100800 100644
--- a/code/modules/events/mice_migration.dm
+++ b/code/modules/events/mice_migration.dm
@@ -23,7 +23,7 @@
priority_announce("Due to [cause], [plural] [name] have [movement] \
into the [location].", "Migration Alert",
- 'sound/effects/mousesqueek.ogg')
+ 'sound/creatures/mousesqueek.ogg')
/datum/round_event/mice_migration/start()
SSminor_mapping.trigger_migration(rand(minimum_mice, maximum_mice))
diff --git a/code/modules/events/wizard/petsplosion.dm b/code/modules/events/wizard/petsplosion.dm
index 7ca7ef2ba2d..33f7718f740 100644
--- a/code/modules/events/wizard/petsplosion.dm
+++ b/code/modules/events/wizard/petsplosion.dm
@@ -5,7 +5,6 @@ GLOBAL_LIST_INIT(petsplosion_candidates, typecacheof(list(
/mob/living/basic/carp/pet/cayenne,
/mob/living/basic/chicken,
/mob/living/basic/cow,
- /mob/living/basic/spider/giant/sgt_araneus,
/mob/living/basic/lizard,
/mob/living/basic/mothroach,
/mob/living/basic/mouse/brown/tom,
@@ -13,9 +12,10 @@ GLOBAL_LIST_INIT(petsplosion_candidates, typecacheof(list(
/mob/living/basic/pig,
/mob/living/basic/rabbit,
/mob/living/basic/sheep,
+ /mob/living/basic/snake,
+ /mob/living/basic/spider/giant/sgt_araneus,
/mob/living/simple_animal/hostile/retaliate/goat,
/mob/living/simple_animal/hostile/retaliate/goose/vomit,
- /mob/living/simple_animal/hostile/retaliate/snake,
/mob/living/simple_animal/parrot,
/mob/living/simple_animal/pet,
/mob/living/simple_animal/sloth,
diff --git a/code/modules/experisci/experiment/experiments.dm b/code/modules/experisci/experiment/experiments.dm
index ab971196092..1959a849598 100644
--- a/code/modules/experisci/experiment/experiments.dm
+++ b/code/modules/experisci/experiment/experiments.dm
@@ -44,7 +44,7 @@
/mob/living/basic/chicken,
/mob/living/basic/cow,
/mob/living/basic/pet/dog/corgi,
- /mob/living/simple_animal/hostile/retaliate/snake,
+ /mob/living/basic/snake,
/mob/living/simple_animal/pet/cat,
)
@@ -234,7 +234,7 @@
/obj/machinery/biogenerator = 3,
/obj/machinery/gibber = 3,
/obj/machinery/chem_master = 3,
- /obj/machinery/atmospherics/components/unary/cryo_cell = 3,
+ /obj/machinery/cryo_cell = 3,
/obj/machinery/harvester = 5,
/obj/machinery/quantumpad = 5
)
diff --git a/code/modules/explorer_drone/control_console.dm b/code/modules/explorer_drone/control_console.dm
index 7b371e8412b..8cc8854f27d 100644
--- a/code/modules/explorer_drone/control_console.dm
+++ b/code/modules/explorer_drone/control_console.dm
@@ -1,6 +1,6 @@
/obj/machinery/computer/exodrone_control_console
name = "exploration drone control console"
- desc = "control eploration drones from intersteller distances. Communication lag not included."
+ desc = "Control exploration drones from interstellar distances. Communication lag not included."
circuit = /obj/item/circuitboard/computer/exodrone_console
//Currently controlled drone
var/obj/item/exodrone/controlled_drone
diff --git a/code/modules/explorer_drone/example_adventures/Theres_a_tree_in_the_middle_of_space.json b/code/modules/explorer_drone/example_adventures/Theres_a_tree_in_the_middle_of_space.json
index 3f9ee41582e..f06b1d25062 100644
--- a/code/modules/explorer_drone/example_adventures/Theres_a_tree_in_the_middle_of_space.json
+++ b/code/modules/explorer_drone/example_adventures/Theres_a_tree_in_the_middle_of_space.json
@@ -1,343 +1,356 @@
{
- "adventure_name": "There's a tree in the middle of space.",
- "version": 1,
- "starting_node": "Tree Start",
- "starting_qualities": {
- "Confusion": 0
- },
- "required_site_traits": [
- "in space"
- ],
- "loot_categories": [
- "research"
- ],
- "scan_band_mods": {
- "Exotic Radiation": 10
- },
- "deep_scan_description": "",
- "triggers": [
- {
- "name": "Confusion Trigger",
- "target_node": "What is wrong with this tree?",
- "requirements": [
- {
- "quality": "Confusion",
- "operator": ">",
- "value": 30
- }
- ]
- }
- ],
- "nodes": [
- {
- "name": "Tree Start",
- "description": "Camera online. Visual signs detect a fully grown, seemingly biological, and live tree located in the middle of the vacuum.\nSensors indicate it is not oxygenating, but energy is being collected via passive solar light from the nearby star.\nBaffling.",
- "choices": [
- {
- "key": "choice 0",
- "name": "Ignore site.",
- "exit_node": "FAIL",
- "delay": 10,
- "delay_message": "Leave this for the botanists to figure out."
- },
- {
- "key": "choice 1",
- "name": "Begin sensor scan.",
- "exit_node": "Biological Scan",
- "delay": 10,
- "delay_message": "Lets get some data."
- }
- ],
- "image": null,
- "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMQAAAAAAAC15h2QtxeAoxVykROizRpxjxIAcgAAWwAAgAAAUAAAZAAAZgC0tLTKysr///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/2AgjmRpnigqrMMqtCvhyvFs17hQuPva67ygTwgcGovA3a61BLaeryj0mapar9isNjCNylpfgWwsLpPPZqBst066le84fB5nRpvdvGDL7/v/JmBeaWiFhIeGbGqLio1ljm2CklKUA4CXmJmaAYidhp9mBmOiYqQEpqZlk3qbra6vsCOenqijtgIHCLG7vL29CQoNCsDCxMPBxw0MxsTLyMLCCwq+1LuVe9VZ0M/c297d4NvZ41vXeueU5N/r4e3o79jkvOb0UAe4+Pf6uMjS7P/TtAAcGKyeQXhT5ClcSKIdwYcHIyKMx7CiwocOwU3cWMmiR4YYQzqM+LGkSQXSUv/2y0jQH0qUJmNqoRSm5ixQbXLK2UmnJ886ToIilFltkk2cNw9B+umz6U87UOsRNXk0KdKrVrOSWWVwqlc+WHHWKnWqrKizZV+QGrA2yte31YDJPTZXrrMEzhbkPSYNWF+4gAFBeICJGTLDxVi2C5yNIxSQikVu48i4j8TLT1i2khwOM+bKVSQaeGLgQOnS+fIBwkiCszfPjqWAnn0ism1hsXO/oM279e3fuqmYeAChN++XKqP9BujP+EcXMKLkoFFm+o3qSH5oJ7L9SPfs3IlEHw/dhfNyLMpbX4+duvvw3uGDj08fCfn0+KVTPI9Ff/T37AHY3nXfFSifgfX9cJ//f/vxh95/1wkoYYQU5oDgfBh+t+B9DsJS4YABfiiDAWWQOGKJKJ6oYidcDdVhUVrFGFZWRl32IlEy0nJLWjyu1VYYrNxY2YxXjZUWW1+0FaSQDiaQ4z0y3OMXX3wxaSUKiWWZTF5c+sVASl8iB9OVbxFH3CVabmOMa9yQ6WYAbHL2Zh+UVRTnbV3NyUlwu120HEuw9WlloO+Mc+c3fCbEH6ES/Ybmn9AwWmdvnu1jaWoHpMBmFYdK+tmLiQqKCaTAebqRnh4d6o6pEqHqEan/sOqiqxbBumqoig42GK0WqUqQY7zCtZKvDgXL37AvEbvNAsaeJ6Zy0JKqErPNYpIj/xqOOKUtU9xu6+1OUekpCJFpLPXtud2mu21UTbhKLraPqCsvuvQ+FdQSqI57bbnxtlHvv/OCK5RsqO4Lr78BA6xwulDR+m4n5iYs8cJNVNyguwYzEi/FE3dsR7UpZJzIxh1z7FO4IJ8gMr860WuAEi/rEHMBM88s8ccpn/AwVhEjTDPMQMsc9M9Cx9HyIJbknMLOEJNC8xpOR/3zy1RPbXXVWD8tM9Rcq3Kx0lesvKORZz2NFtVmnWJ2j2NLAnYsiJCd9tlzz7122XTnnfbb2dxUi96A1x044GDwnc0Zfwuu+OCLK274c4UkzvjkZj3+ldxkUY5AApt3noDlldF1zP/YBAyzuemcp4665wGBDlcDeCUA+zKzyx77Arfnvjnuy+C+u+uADXPXMsTHXvzxxid/PPC8OEAYmnLBPoz0ttMee+3YXx/958y/oqsDl4hel/jkjz9+Md17Rf3620/fvu3uxy97A+lPVT75ic2lJWLDWD7AE/97QQCT1qv3sU9+6ytGAxTIQL7FpiLJiCD/JggOYJxKXAPMIAA3KCp1MHB6H5wfCEcowgRoUIAc/F8L3CSrr/EiGAsc4QKhEcMZwpCG0DihClHIQxVeaYdA1KEQAWioD9pQhEesoRJTOMQe/k9ITQwiEzloQ/q9sIpKxOENt9iAKHpxgw76ohOnKED/LWJRGJrIIhfVWEUxSnGMPDQOGd+4wwME0I76COAC2MhHNPZhjWbk4xzd2MTeNBGPuBiAPg6wyEbiIlMiaEBKYrjHQOJQG5YE5BbpSMhByvGQiixNKBlpGlI+8h5a0OQZg2ECVfYRhoOMJRx36JxZ/k+UbMGjKEupyERi4pUzjGQmV9lGWXLSkxiMoy+ICcxmNsCWxvRi/VYzw2pa85rYvKYKt8nNbnrzm96c5h+G6UwudhKacBTnOLPJznYuEJzwjCc41blOctoTlug8JjTpiSZ3+lOb3LTj/wSqSHlycwQPeB4//8jMe2KRgwJNZDQJaCaFLlQge6ykJP/ZTo3iYbGgHx3oPC+6CZRQspwNNakwEMnSE5L0FRndaEwXqFGO0lSmG32pQmLK043e1KYz7KlO5dHTouKUo0YdKjmMalSk4jSmSh3HAqb61KpqtKZBtWpOo1oNpmoVq9dkKrWMEwIAOw=="
- },
- {
- "name": "Biological Scan",
- "description": "You attempt to scan for clues regarding the tree's nature. It appears to be a fully mature oak tree. \n\nApproximated height is 13 ft, 6.4 inches. \n\nSubject sees no sign of an outer coating or otherwise layer protecting it from the void of space.\n\nSubject's surface temperature is 293.7 kelvin, as though it were sitting indoors.",
- "choices": [
- {
- "key": "choice 2",
- "name": "Check Sensor Integrity.",
- "exit_node": "Its Not You...",
- "on_selection_effects": [
- {
- "effect_type": "Add",
- "quality": "Confusion",
- "value": 5
- }
- ],
- "delay": 50,
- "delay_message": "This can't be right."
- },
- {
- "key": "choice 4",
- "name": "Attempt to take sample.",
- "exit_node": "Sample Taken",
- "on_selection_effects": [
- {
- "effect_type": "Add",
- "quality": "Confusion",
- "value": 3
- }
- ],
- "delay": 40,
- "delay_message": "Snip snip."
- },
- {
- "key": "choice 6",
- "name": "Examine Tree Roots.",
- "exit_node": "Examine Roots",
- "delay": 10
- },
- {
- "key": "choice 9",
- "name": "Sequence Sample Radiation with background noise.",
- "exit_node": "Background Analysis",
- "requirements": [
- {
- "quality": "Sample",
- "operator": ">=",
- "value": 1
- }
- ],
- "delay": 0,
- "delay_message": "This can't be real."
- }
- ],
- "image": null,
- "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMQAAAAAAAC15h2QtxeAoxVykROizRpxjxIAcgAAWwAAgAAAUAAAZAAAZgC0tLTKysr///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/2AgjmRpnigqrMMqtCvhyvFs17hQuPva67ygTwgcGovA3a61BLaeryj0mapar9isNjCNylpfgWwsLpPPZqBst066le84fB5nRpvdvGDL7/v/JmBeaWiFhIeGbGqLio1ljm2CklKUA4CXmJmaAYidhp9mBmOiYqQEpqZlk3qbra6vsCOenqijtgIHCLG7vL29CQoNCsDCxMPBxw0MxsTLyMLCCwq+1LuVe9VZ0M/c297d4NvZ41vXeueU5N/r4e3o79jkvOb0UAe4+Pf6uMjS7P/TtAAcGKyeQXhT5ClcSKIdwYcHIyKMx7CiwocOwU3cWMmiR4YYQzqM+LGkSQXSUv/2y0jQH0qUJmNqoRSm5ixQbXLK2UmnJ886ToIilFltkk2cNw9B+umz6U87UOsRNXk0KdKrVrOSWWVwqlc+WHHWKnWqrKizZV+QGrA2yte31YDJPTZXrrMEzhbkPSYNWF+4gAFBeICJGTLDxVi2C5yNIxSQikVu48i4j8TLT1i2khwOM+bKVSQaeGLgQOnS+fIBwkiCszfPjqWAnn0ism1hsXO/oM279e3fuqmYeAChN++XKqP9BujP+EcXMKLkoFFm+o3qSH5oJ7L9SPfs3IlEHw/dhfNyLMpbX4+duvvw3uGDj08fCfn0+KVTPI9Ff/T37AHY3nXfFSifgfX9cJ//f/vxh95/1wkoYYQU5oDgfBh+t+B9DsJS4YABfiiDAWWQOGKJKJ6oYidcDdVhUVrFGFZWRl32IlEy0nJLWjyu1VYYrNxY2YxXjZUWW1+0FaSQDiaQ4z0y3OMXX3wxaSUKiWWZTF5c+sVASl8iB9OVbxFH3CVabmOMa9yQ6WYAbHL2Zh+UVRTnbV3NyUlwu120HEuw9WlloO+Mc+c3fCbEH6ES/Ybmn9AwWmdvnu1jaWoHpMBmFYdK+tmLiQqKCaTAebqRnh4d6o6pEqHqEan/sOqiqxbBumqoig42GK0WqUqQY7zCtZKvDgXL37AvEbvNAsaeJ6Zy0JKqErPNYpIj/xqOOKUtU9xu6+1OUekpCJFpLPXtud2mu21UTbhKLraPqCsvuvQ+FdQSqI57bbnxtlHvv/OCK5RsqO4Lr78BA6xwulDR+m4n5iYs8cJNVNyguwYzEi/FE3dsR7UpZJzIxh1z7FO4IJ8gMr860WuAEi/rEHMBM88s8ccpn/AwVhEjTDPMQMsc9M9Cx9HyIJbknMLOEJNC8xpOR/3zy1RPbXXVWD8tM9Rcq3Kx0lesvKORZz2NFtVmnWJ2j2NLAnYsiJCd9tlzz7122XTnnfbb2dxUi96A1x044GDwnc0Zfwuu+OCLK274c4UkzvjkZj3+ldxkUY5AApt3noDlldF1zP/YBAyzuemcp4665wGBDlcDeCUA+zKzyx77Arfnvjnuy+C+u+uADXPXMsTHXvzxxid/PPC8OEAYmnLBPoz0ttMee+3YXx/958y/oqsDl4hel/jkjz9+Md17Rf3620/fvu3uxy97A+lPVT75ic2lJWLDWD7AE/97QQCT1qv3sU9+6ytGAxTIQL7FpiLJiCD/JggOYJxKXAPMIAA3KCp1MHB6H5wfCEcowgRoUIAc/F8L3CSrr/EiGAsc4QKhEcMZwpCG0DihClHIQxVeaYdA1KEQAWioD9pQhEesoRJTOMQe/k9ITQwiEzloQ/q9sIpKxOENt9iAKHpxgw76ohOnKED/LWJRGJrIIhfVWEUxSnGMPDQOGd+4wwME0I76COAC2MhHNPZhjWbk4xzd2MTeNBGPuBiAPg6wyEbiIlMiaEBKYrjHQOJQG5YE5BbpSMhByvGQiixNKBlpGlI+8h5a0OQZg2ECVfYRhoOMJRx36JxZ/k+UbMGjKEupyERi4pUzjGQmV9lGWXLSkxiMoy+ICcxmNsCWxvRi/VYzw2pa85rYvKYKt8nNbnrzm96c5h+G6UwudhKacBTnOLPJznYuEJzwjCc41blOctoTlug8JjTpiSZ3+lOb3LTj/wSqSHlycwQPeB4//8jMe2KRgwJNZDQJaCaFLlQge6ykJP/ZTo3iYbGgHx3oPC+6CZRQspwNNakwEMnSE5L0FRndaEwXqFGO0lSmG32pQmLK043e1KYz7KlO5dHTouKUo0YdKjmMalSk4jSmSh3HAqb61KpqtKZBtWpOo1oNpmoVq9dkKrWMEwIAOw=="
- },
- {
- "name": "Its Not You...",
- "description": "After re-connection is established, your sensors appear fine. Tree has not moved in the slightest since last observed. Temperature has fluxuated 0.2 kelvin upwards, as expected of a plant under direct light.\nLets try again.",
- "choices": [
- {
- "key": "choice 3",
- "name": "Restart biological scan.",
- "exit_node": "Biological Scan",
- "delay": 25,
- "delay_message": "God damnit."
- }
- ],
- "image": null,
- "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD////v7+/h4eEAAAAAAAAAAAAD/xi63P4wykmrvTjrzbv/YCiOZBkJaJqaLKOubSy7b23fODxPOb7/m4FASBRofEBeT1W6JU3DYaRIjQqfkCWKg1xoddjSQEgQlM/mdDkc0Fa+8PiWLSIM7Pj73RxOlVF/ITlKNXSGDXp5iiFoaBlqfpFyk12HMgSYmZkfmppmmJ8gjXwUf2lglqmqq6ytrq+wsbKztLW2t7i5um2Ug669uyBCKMNRc4Q9qXHBJlVUFMbRV6pfR04ONszQzlZRlm7IveLaimZ7eJAESUsfyVnX2hfqv/Nv4vfZ8RWJ/Hkdn6NGtRsFyEg4VLwK6UvVqROdgMcWSpxIsaLFixgzatzIsf+jR1gIP7YbN6uaSAn4wFGbdNJFsZcpFRqS09IBt2kW3CkzWdNmNyIYpIWkw9Nevgbwat2ccNPbTnbWjtKQWfGnVZwzoQaNqVXXkDFWGx3qeoIry2CJzJ05p6aPTpRmfSXV1a/u2jM7TuldA8LXO6kXFemh5ihn3Lc9A9h1ZaqxpMNkK9rl5+EMKIGM9g5FSjJjv4aVOwEc/Q8iXx6ODSo5ualOQ9Bs0qVJTLu27du4c+vezbu379/AgwsfTry48ePIkytfqHp5xhfLadby+1soMJDLbhchlqIYpVbXa14dz718NMBEz/ZsWsU8zMhY1CdmL+VE+/ObgWSvPR4rj/f/xqxUFG1fVfHIUgLCN58zR5ABySpwbAAdZ1TNMgZYF9YHjWmsDAgNeglNqFSBJJYiG14JUmcYiHNZWJcE6HD4FGIrVuiFjROxJeNYChoFWUS5lBPjOTO2iM2PKuki2F1qfdPjjUjSeMuSk82Uml4fRimlLVR2OUAYBGHpo5aV4OJll1iYRkqWhag4FY75WXhmlTOoedo/ZVKI40Jz+pOEnX2ZsqcCeVJ0piEQieJhiEx0RBkrd6J2IiQFVXqPbZjEYqdmll6Jz0avtUaCqEFtaiqnekmHUagOhSZapvJMeioanXa2KqukZoCrJoruCKNmCngKZGC7urprPRKq+QZBP2XFKRGunBwL6waZjIbiBInu9hoj0o5wraRiOadrsX1kK24HvBK25rnstuvuu/DGK++89NZr77345qvvvhYlAAA7"
- },
- {
- "name": "Sample Taken",
- "description": "You collect and project a small sample of tree bark off the plant. The instant that the bark is removed from the tree, as though it suddenly remembered what it was, the moisture content of the bark freezes over, and implodes into small microparticles of splinters.\nSmall radioactive signature detected.",
- "choices": [
- {
- "key": "choice 5",
- "name": "Well that was... unexpected.",
- "exit_node": "Biological Scan",
- "delay": 0,
- "delay_message": "Maybe something else might work better.",
- "on_selection_effects": [
- {
- "effect_type": "Add",
- "quality": "Sample",
- "value": 1
- }
- ]
- }
- ],
- "image": null,
- "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAABSLiiPVjtyRS9mOTFbNyYAAAAD/xi63P4wykmrvTjrzbv/YCiOZGmeaKqubOu+sDUQxTDbeK7vfF/3saCwcxPcCMckcqlM2pDPnnRKrUqH2IdAYDBwu+Bwl2Agm8sE8iy9Zrqbb2Z0bq3b74W8Xp+1bP+Af2KDhIVlh2eJaUtsi3CPcU43d5QDe5cFfSKBnJ2en50Ff6JboqYCBWiLq46tkK+RUJOTmJmatxyguqSovae/vsGirK2NjU21trjLQp+8wNDCwnmo1MnM2Nna29zd3t/g4eLj5OXm59o5Rjo/QOjvLaKwkrKylfdW8FleXImIBm0CxppXD4c9fAgT5tCn4Iuhh4fG/DNTjNHAi4/oKERYq/+cro8gPYXxR7EkK4EEUxbUOCVZHoabQoZ8NkqaKWI4BR7DGKcjTG4yaZaySRSatQLGfP5ciqHX0GhQpzGdSrWq1atYs2rdyrWr169gw4pVsc7G2LMLkM46SOkl2nc86W3E97aFgLh4Dc7dq6NuhC0TVVlUOY8l38N9szocREYiyYqEMdJZibjylW+AIRIiqUowyrwDJ+u1XMelsm6CNKtmHHiRZ8iuQGecVdklZpm4V3NWREznYNmhaeNRCg638eOBhrUWjPP3zshNDNuwzRW5dZrQmms3BhzSNb8SrIPCXvTudtjzMIEngVxo+ajDtKOkvt5u0Jrw3/s6yqd+Nk7/7uUn4FH+VaWfKAUmqOCCDDbo4IMQRijhhBRWaOGFGGao4YYcdujhhyCGKOKFRsgxy4jaBEeZOyi60J2JK1piS2ItcvDiaMIpVGMEv0GnIo46grgFbM/dKBppC004kXzo3fiGdJb51wUgiKTBnHNOzsYWkpd1xZpjrTHJnY+vQGlZOztMBUZmrO0mZo9Zwggkl/mkKc5qIy3n2nlExrnWnHROcRueYjSm55Wr+Ebmj2YeZpo4bBJqyG6Inqeon0duRF84kuJJKW98Nrkojlu2dYlHkXaq6qehNvfZqHI2+ihq4lGpKhisttpbbKNm6sN3t9Wam2q5Vtrqq5jesKk3jsI220mheuq665jJzoqqs9gGcqi0211KGLBUZYutciUZG6q3cREnlrjiPcZtTqIiAW597H5E07uuiqqehPXONIq57+6rYb81PWUTvmksuyHBTjUc1XnVmOLWjgFkG+CBNk1MsRb1kiegLxtf4KzHB4b8Qa0XA2OyfZ6QjODKywwlM8w012zzzTjnrPNWCQAAOw=="
- },
- {
- "name": "Examine Roots",
- "description": "All plant matter has to derive energy and moisture from someplace. Examining the oak tree's roots reveals that the roots present all appear to splay out, similar to how a normal tree would. However, those roots then proceed to double back in on itself. This might suggest that the tree is obtaining nutrients from... itself.",
- "choices": [
- {
- "key": "choice 7",
- "name": "That's fucking stupid.",
- "exit_node": "Biological Scan",
- "on_selection_effects": [
- {
- "effect_type": "Add",
- "quality": "Confusion",
- "value": {
- "value_type": "random",
- "low": 6,
- "high": 10
- }
- }
- ],
- "delay": 0,
- "delay_message": "What the hell kind of tree even IS this?"
- },
- {
- "key": "choice 8",
- "name": "Obtain biological sample from roots.",
- "exit_node": "Sample Taken",
- "delay": 10,
- "delay_message": "This is why we hire botanists on-site."
- }
- ],
- "image": null,
- "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMQAAAAAAAC15h2QtxeAoxVykROizRpxjxIAcgAAWwAAgAAAUAAAZAAAZgC0tLTKysr///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/2AgjmRpnigqrMMqtCvhyvFs17hQuPva67ygTwgcGovA3a61BLaeryj0mapar9isNjCNylpfgWwsLpPPZqBst066le84fB5nRpvdvGDL7/v/JmBeaWiFhIeGbGqLio1ljm2CklKUA4CXmJmaAYidhp9mBmOiYqQEpqZlk3qbra6vsCOenqijtgIHCLG7vL29CQoNCsDCxMPBxw0MxsTLyMLCCwq+1LuVe9VZ0M/c297d4NvZ41vXeueU5N/r4e3o79jkvOb0UAe4+Pf6uMjS7P/TtAAcGKyeQXhT5ClcSKIdwYcHIyKMx7CiwocOwU3cWMmiR4YYQzqM+LGkSQXSUv/2y0jQH0qUJmNqoRSm5ixQbXLK2UmnJ886ToIilFltkk2cNw9B+umz6U87UOsRNXk0KdKrVrOSWWVwqlc+WHHWKnWqrKizZV+QGrA2yte31YDJPTZXrrMEzhbkPSYNWF+4gAFBeICJGTLDxVi2C5yNIxSQikVu48i4j8TLT1i2khwOM+bKVSQaeGLgQOnS+fIBwkiCszfPjqWAnn0ism1hsXO/oM279e3fuqmYeAChN++XKqP9BujP+EcXMKLkoFFm+o3qSH5oJ7L9SPfs3IlEHw/dhfNyLMpbX4+duvvw3uGDj08fCfn0+KVTPI9Ff/T37AHY3nXfFSifgfX9cJ//f/vxh95/1wkoYYQU5oDgfBh+t+B9DsJS4YABfiiDAWWQOGKJKJ6oYidcDdVhUVrFGFZWRl32IlEy0nJLWjyu1VYYrNxY2YxXjZUWW1+0FaSQDiaQ4z0y3OMXX3wxaSUKiWWZTF5c+sVASl8iB9OVbxFH3CVabmOMa9yQ6WYAbHL2Zh+UVRTnbV3NyUlwu120HEuw9WlloO+Mc+c3fCbEH6ES/Ybmn9AwWmdvnu1jaWoHpMBmFYdK+tmLiQqKCaTAebqRnh4d6o6pEqHqEan/sOqiqxbBumqoig42GK0WqUqQY7zCtZKvDgXL37AvEbvNAsaeJ6Zy0JKqErPNYpIj/xqOOKUtU9xu6+1OUekpCJFpLPXtud2mu21UTbhKLraPqCsvuvQ+FdQSqI57bbnxtlHvv/OCK5RsqO4Lr78BA6xwulDR+m4n5iYs8cJNVNyguwYzEi/FE3dsR7UpZJzIxh1z7FO4IJ8gMr860WuAEi/rEHMBM88s8ccpn/AwVhEjTDPMQMsc9M9Cx9HyIJbknMLOEJNC8xpOR/3zy1RPbXXVWD8tM9Rcq3Kx0lesvKORZz2NFtVmnWJ2j2NLAnYsiJCd9tlzz7122XTnnfbb2dxUi96A1x044GDwnc0Zfwuu+OCLK274c4UkzvjkZj3+ldxkUY5AApt3noDlldF1zP/YBAyzuemcp4665wGBDlcDeCUA+zKzyx77Arfnvjnuy+C+u+uADXPXMsTHXvzxxid/PPC8OEAYmnLBPoz0ttMee+3YXx/958y/oqsDl4hel/jkjz9+Md17Rf3620/fvu3uxy97A+lPVT75ic2lJWLDWD7AE/97QQCT1qv3sU9+6ytGAxTIQL7FpiLJiCD/JggOYJxKXAPMIAA3KCp1MHB6H5wfCEcowgRoUIAc/F8L3CSrr/EiGAsc4QKhEcMZwpCG0DihClHIQxVeaYdA1KEQAWioD9pQhEesoRJTOMQe/k9ITQwiEzloQ/q9sIpKxOENt9iAKHpxgw76ohOnKED/LWJRGJrIIhfVWEUxSnGMPDQOGd+4wwME0I76COAC2MhHNPZhjWbk4xzd2MTeNBGPuBiAPg6wyEbiIlMiaEBKYrjHQOJQG5YE5BbpSMhByvGQiixNKBlpGlI+8h5a0OQZg2ECVfYRhoOMJRx36JxZ/k+UbMGjKEupyERi4pUzjGQmV9lGWXLSkxiMoy+ICcxmNsCWxvRi/VYzw2pa85rYvKYKt8nNbnrzm96c5h+G6UwudhKacBTnOLPJznYuEJzwjCc41blOctoTlug8JjTpiSZ3+lOb3LTj/wSqSHlycwQPeB4//8jMe2KRgwJNZDQJaCaFLlQge6ykJP/ZTo3iYbGgHx3oPC+6CZRQspwNNakwEMnSE5L0FRndaEwXqFGO0lSmG32pQmLK043e1KYz7KlO5dHTouKUo0YdKjmMalSk4jSmSh3HAqb61KpqtKZBtWpOo1oNpmoVq9dkKrWMEwIAOw=="
- },
- {
- "name": "Background Analysis",
- "description": "You compare the radioactive energy bands of the sample collected earlier with that of the nearby solar enviroment.\nNothing.\nThere is nothing nearby that matches the passive signal of the tree, or the bark, or anything similar.\nThis is really starting to get on your nerves.",
- "choices": [
- {
- "key": "choice 10",
- "name": "Smash your desk in frustration.",
- "exit_node": "FAIL",
- "delay": 50,
- "delay_message": "No amount of pay is worth dealing with magical plant juju."
- },
- {
- "key": "choice 11",
- "name": "Check every known energy spectroscopy database.",
- "exit_node": "Sample Match Found",
- "delay": 900,
- "delay_message": "You NEED an answer. You DESERVE an answer."
- }
- ],
- "image": null,
- "on_enter_effects": [
- {
- "effect_type": "Add",
- "quality": "Confusion",
- "value": {
- "value_type": "random",
- "low": 3,
- "high": 5
- }
- }
- ],
- "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD///9ZVlKsMjJpampGR0cAAAAD/xi63P4wykmFpTjrDa0XXCiOZGlqQ0qsazqIXyx9Z23feKayfP/WskgwRywqCsikcslsOpGpgGvQNDo8lYt1W4I+v2CvMhUuI0/YiZbL5nxdhkJ8Lq/T6eZ8HRmHUtuAgRp6T3B2SXdNfYeJc3CCkJEYjISVYZKRQ5gajZSdi0yboqM3nnWkqKmCpgaqrq9GBrKzs7AKaYG4tji0vbu/wCW6wZpqNMHIOAM9zDw/IzEgHcVt1KOWZQ1TU4LDV2vJOAVU2GZkY5VF4NPr4SRM53yI8/Lw9uVvBcLuknqGn4cqLQIYhwy/g0fwKdSDsCEGggtDOZwoAiLFi5sAYtwoqf/XIVjeOKrqRUukjZAmGVjDGC2lSyAts7R7GW5ZM2bPNERDGSAmzWA2b/pAc+yBT0ArVeXhsC2oj5wnefaU+pNBxDJNXUAqyq6qhKthyCUR+4QLVa5ej5AFO3ZJPGw3qE5N22DsWiUD6Tm5e/cqCbk96dZtQgZip3rjwIIa90fwqrBUDAfcQ0hyilaOIWG7zIoSYryd73DLrJntNlOIO2WVQ/raYrYKW/8CCNuJbH6S8aS7vSCpq9C8gxMMzns48dudj9/WqFw2yZKvfDc38Rxzc+kiq09f/nw7b+wNwV9HuwuwSvLeL14wjz49pm3Qds7sbd59jh1Co3CQP1+8/Rr/TgnVQnxHNVDgf0QEKCBUIRxIX3sIAiigMwzCAKF/cc1H1xQTVvjXhRCqE6IosU2Q1YkiajiViin+VhthWW0l1YhevQjjafrIKI0QLP5kI2GMBWkbG2fVx1FiP/oxRl9DEiEXCDsKhuSPazFpBg5P9miSkHmlpleXbbkVUVRRTkOakl7mRg9fsJmQ5Zl2DaDmJ4XVwZkZYHbpoU726eZCaID28RYYeRFEToQVeVaYLHIwOkugk70GqWiNIeoGQJc5qumclOU5qUGWXhraFNU1yumpdoAa6ganZkrLpJ2G5qido606CKoGwDErrqaaSlKttrIKq2r/DGvHr39aF2wIgsYaduKzqyUhhbLLjsArp3BVW0Oz3OpWlrY5dCsuKOByMS635QpyLaTEGenauZ2M5y4m696B4Lz0spLuRMnt25BH9vr7b3XUChwOwbIYfBDCBSscDMIOL0xwxO5ATPHB2kVHY7oTg7RxuR0rhyFFIYv8MUYZX5xMySoDk3LLD3dXbQIAOw=="
- },
- {
- "name": "Sample Match Found",
- "description": "After an extensive algorithm search on the controller end, you have a single match to this specific band and style of energy.\nThe problem, is that the source of said radiation is coming not only from Space Station 13, no.\nIt's coming from the Space Station 13 Research Department.\nWhat the fuck?",
- "choices": [
- {
- "key": "choice 12",
- "name": "Something must be wrong with the drone.",
- "exit_node": "Its Not You...",
- "on_selection_effects": [
- {
- "effect_type": "Add",
- "quality": "Confusion",
- "value": {
- "value_type": "random",
- "low": 6,
- "high": 10
- }
- }
- ],
- "delay": 30,
- "delay_message": "Lousy piece of junk must be scanning the station instead of the target."
- },
- {
- "key": "choice 13",
- "name": "Perhaps that sample was tainted. Collect a new sample.",
- "exit_node": "Sample Taken",
- "delay": 60,
- "delay_message": "Lets try again, but carefully."
- },
- {
- "key": "choice 14",
- "name": "Remember the Christmas Party.",
- "exit_node": "The Christmas Party",
- "requirements": [
- {
- "quality": "Confusion",
- "operator": "<=",
- "value": 25
- }
- ],
- "delay": 100,
- "delay_message": "Wait a gosh darn fucking second."
- }
- ],
- "image": null,
- "on_enter_effects": [
- {
- "effect_type": "Add",
- "quality": "Confusion",
- "value": 10
- }
- ],
- "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD////v7+/h4eEAAAAAAAAAAAAD/xi63P4wykmrvTjrzbv/YCiOZBkJaJqaLKOubSy7b23fODxPOb7/m4FASBRofEBeT1W6JU3DYaRIjQqfkCWKg1xoddjSQEgQlM/mdDkc0Fa+8PiWLSIM7Pj73RxOlVF/ITlKNXSGDXp5iiFoaBlqfpFyk12HMgSYmZkfmppmmJ8gjXwUf2lglqmqq6ytrq+wsbKztLW2t7i5um2Ug669uyBCKMNRc4Q9qXHBJlVUFMbRV6pfR04ONszQzlZRlm7IveLaimZ7eJAESUsfyVnX2hfqv/Nv4vfZ8RWJ/Hkdn6NGtRsFyEg4VLwK6UvVqROdgMcWSpxIsaLFixgzatzIsf+jR1gIP7YbN6uaSAn4wFGbdNJFsZcpFRqS09IBt2kW3CkzWdNmNyIYpIWkw9Nevgbwat2ccNPbTnbWjtKQWfGnVZwzoQaNqVXXkDFWGx3qeoIry2CJzJ05p6aPTpRmfSXV1a/u2jM7TuldA8LXO6kXFemh5ihn3Lc9A9h1ZaqxpMNkK9rl5+EMKIGM9g5FSjJjv4aVOwEc/Q8iXx6ODSo5ualOQ9Bs0qVJTLu27du4c+vezbu379/AgwsfTry48ePIkytfqHp5xhfLadby+1soMJDLbhchlqIYpVbXa14dz718NMBEz/ZsWsU8zMhY1CdmL+VE+/ObgWSvPR4rj/f/xqxUFG1fVfHIUgLCN58zR5ABySpwbAAdZ1TNMgZYF9YHjWmsDAgNeglNqFSBJJYiG14JUmcYiHNZWJcE6HD4FGIrVuiFjROxJeNYChoFWUS5lBPjOTO2iM2PKuki2F1qfdPjjUjSeMuSk82Uml4fRimlLVR2OUAYBGHpo5aV4OJll1iYRkqWhag4FY75WXhmlTOoedo/ZVKI40Jz+pOEnX2ZsqcCeVJ0piEQieJhiEx0RBkrd6J2IiQFVXqPbZjEYqdmll6Jz0avtUaCqEFtaiqnekmHUagOhSZapvJMeioanXa2KqukZoCrJoruCKNmCngKZGC7urprPRKq+QZBP2XFKRGunBwL6waZjIbiBInu9hoj0o5wraRiOadrsX1kK24HvBK25rnstuvuu/DGK++89NZr77345qvvvhYlAAA7"
- },
- {
- "name": "The Christmas Party",
- "description": "Hold on. Last Christmas, the Research Director was incredibly hammered. He made a big mention that his brand new festivus pole was actually some kind of astrological... something something. You can't remember the whole details, because you were smashed as well. However, briefly, the RD did keep that festivus pole for awhile, he might even still have it somewhere.\nMaybe...?",
- "choices": [
- {
- "key": "choice 15",
- "name": "Wait a minute, was that a god damn...",
- "exit_node": "Rod.",
- "delay": 100,
- "delay_message": "Immovable Rod?"
- }
- ],
- "image": null,
- "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD/AACmAAD///+mpqYAAAAAAAAD/xi63P4wykmrvTjrzbv/YCiOZGmejKCubOu6aCzP4WvfeD4IQ+//Pppw+MkZj6udkgdsOp/EqFSBrNqWwQ9hy+16v9ypeGM9YpnAE3hNKLTfhbG8kuTZz/j7/fmb+/8TbIJefIVNgIiJGgWMjY6PkJGRipSVlpeYmZqbnJ2en6ChoqOkpRplqDdYpqyprnpKhnyslq9leFkYg2u0QrZmaLkgu8S9JDg7Ksl2yrB7UDJw0m6QxiFfedk9wbKH1tbEW9TT05Lmjd/pJpPq7e7v8PHy8/T19vf4+fr7Kb9W/Jn8pcLiBKAcgVZwdethkAZCJAoXFmx47KEOWLMeAAlHMf+DRVXctIT70jHCxxYEhXkYKajkgpMRGZZgKY5LHJcJ6zTTNtHEm5rjgsK5WZKZs2xHn2WccY6RSwdJkaaUOOApoHDbqFK16ofmF6Fg20Aa8IhrpbBBm6plZ7aTIwhr0bWdS7eu3bt48+rdy7ev37+AAwseTLiw4cOI0/1LfPAkC8YlHINUApmD5MncVFZ+cPmK0qWbX3Z2MbVbaCqjd37eCjk1i9JaZR5OHTN2z8Gua9v2wavvaNjeKgygqbcz8KocvBLAexn4MOVb5jZfjVwk9DBW/S3bTn3E9S5cUXFvphqaCOhBs7/WGbU96PNr0EpTT96o1Kjv4ZOT/xbn/f921AWnBlhNWQXggZndFkNcZv2X1YOxsCZENXdJBWGCWp2mQRc+YLibIRpaQMyHEoVYgVfDcUFiHyYGopxQTgwFYosugsFfOXGZQyMGN+boI1E78vjjkHIF+QGRahkZxVpKNunkk1BGKeWUVFZp5ZVYZqnllogkAAA7"
- },
- {
- "name": "Rod.",
- "description": "You cross reference your documentation. Sure enough, the \"festivus rod\" collected was actually an immovable rod.\nEnergy detected from the rod is the exact same coming off of the tree, as well. It's all making sense now. The Immovable rod is producing a kind of unique blackbody radiation that is providing sample heat and light for what is effectively an internal cold fusion process, and producing just enough of that radiation to create a kind of micro-enviromental bubble around the biosignature of the tree.\n\nThis would make the first time an immovable rod would exist in tandem with a biological source. You jot down some research notes on your findings, which could easily produce some kind of experimental tech, no doubt.",
- "choices": [
- {
- "key": "choice 16",
- "name": "Snap a photo",
- "exit_node": "Epilogue.",
- "delay": 40,
- "delay_message": "You could easily win an award for these findings!"
- }
- ],
- "image": "default"
- },
- {
- "name": "Epilogue.",
- "description": "You take a photo with the onboard camera on the drone. Suddenly, the immovable rod inside the tree explodes out of the wooden biological shell, and produces a blank, blurry photo.\nWhat the fuck?",
- "choices": [
- {
- "key": "choice 17",
- "name": "God damnit.",
- "exit_node": "WIN",
- "delay": 10,
- "delay_message": "Some things were just not meant for man to know."
- }
- ],
- "image": "default"
- },
- {
- "name": "What is wrong with this tree?",
- "description": "This is ridiculous. Nothing about this dumbass tree makes sense. It makes no sense, it's just sitting there, living and making a MOCKERY of all of science!\nYou didn't get your degree in advanced plasma-physics for this!",
- "choices": [
- {
- "key": "choice 18",
- "name": "The world can never know about this dumbass stupid plant.",
- "exit_node": "FAIL_DEATH",
- "delay": 60,
- "delay_message": "Activating drone self-destruct."
- },
- {
- "key": "choice 19",
- "name": "Take a moment to calm down.",
- "exit_node": "Biological Scan",
- "on_selection_effects": [
- {
- "effect_type": "Add",
- "quality": "Confusion",
- "value": {
- "value_type": "random",
- "low": -3,
- "high": -5
- }
- }
- ],
- "delay": 20,
- "delay_message": "Breathe."
- }
- ],
- "image": "default"
- }
- ]
- }
+ "adventure_name": "There's a tree in the middle of space.",
+ "version": 1,
+ "starting_node": "Tree Start",
+ "starting_qualities": {
+ "Confusion": 0
+ },
+ "required_site_traits": [
+ "in space"
+ ],
+ "loot_categories": [
+ "research"
+ ],
+ "scan_band_mods": {
+ "Exotic Radiation": 10
+ },
+ "deep_scan_description": "",
+ "triggers": [
+ {
+ "name": "Confusion Trigger",
+ "target_node": "What is wrong with this tree?",
+ "requirements": [
+ {
+ "quality": "Confusion",
+ "operator": ">",
+ "value": 30
+ }
+ ]
+ }
+ ],
+ "nodes": [
+ {
+ "name": "Tree Start",
+ "description": "Camera online. Visual signs detect a fully grown, seemingly biological, and live tree located in the middle of the vacuum.\nSensors indicate it is not oxygenating, but energy is being collected via passive solar light from the nearby star.\nBaffling.",
+ "choices": [
+ {
+ "key": "choice 0",
+ "name": "Ignore site.",
+ "exit_node": "FAIL",
+ "delay": 10,
+ "delay_message": "Leave this for the botanists to figure out."
+ },
+ {
+ "key": "choice 1",
+ "name": "Begin sensor scan.",
+ "exit_node": "Biological Scan",
+ "delay": 10,
+ "delay_message": "Lets get some data."
+ }
+ ],
+ "image": null,
+ "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMQAAAAAAAC15h2QtxeAoxVykROizRpxjxIAcgAAWwAAgAAAUAAAZAAAZgC0tLTKysr///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/2AgjmRpnigqrMMqtCvhyvFs17hQuPva67ygTwgcGovA3a61BLaeryj0mapar9isNjCNylpfgWwsLpPPZqBst066le84fB5nRpvdvGDL7/v/JmBeaWiFhIeGbGqLio1ljm2CklKUA4CXmJmaAYidhp9mBmOiYqQEpqZlk3qbra6vsCOenqijtgIHCLG7vL29CQoNCsDCxMPBxw0MxsTLyMLCCwq+1LuVe9VZ0M/c297d4NvZ41vXeueU5N/r4e3o79jkvOb0UAe4+Pf6uMjS7P/TtAAcGKyeQXhT5ClcSKIdwYcHIyKMx7CiwocOwU3cWMmiR4YYQzqM+LGkSQXSUv/2y0jQH0qUJmNqoRSm5ixQbXLK2UmnJ886ToIilFltkk2cNw9B+umz6U87UOsRNXk0KdKrVrOSWWVwqlc+WHHWKnWqrKizZV+QGrA2yte31YDJPTZXrrMEzhbkPSYNWF+4gAFBeICJGTLDxVi2C5yNIxSQikVu48i4j8TLT1i2khwOM+bKVSQaeGLgQOnS+fIBwkiCszfPjqWAnn0ism1hsXO/oM279e3fuqmYeAChN++XKqP9BujP+EcXMKLkoFFm+o3qSH5oJ7L9SPfs3IlEHw/dhfNyLMpbX4+duvvw3uGDj08fCfn0+KVTPI9Ff/T37AHY3nXfFSifgfX9cJ//f/vxh95/1wkoYYQU5oDgfBh+t+B9DsJS4YABfiiDAWWQOGKJKJ6oYidcDdVhUVrFGFZWRl32IlEy0nJLWjyu1VYYrNxY2YxXjZUWW1+0FaSQDiaQ4z0y3OMXX3wxaSUKiWWZTF5c+sVASl8iB9OVbxFH3CVabmOMa9yQ6WYAbHL2Zh+UVRTnbV3NyUlwu120HEuw9WlloO+Mc+c3fCbEH6ES/Ybmn9AwWmdvnu1jaWoHpMBmFYdK+tmLiQqKCaTAebqRnh4d6o6pEqHqEan/sOqiqxbBumqoig42GK0WqUqQY7zCtZKvDgXL37AvEbvNAsaeJ6Zy0JKqErPNYpIj/xqOOKUtU9xu6+1OUekpCJFpLPXtud2mu21UTbhKLraPqCsvuvQ+FdQSqI57bbnxtlHvv/OCK5RsqO4Lr78BA6xwulDR+m4n5iYs8cJNVNyguwYzEi/FE3dsR7UpZJzIxh1z7FO4IJ8gMr860WuAEi/rEHMBM88s8ccpn/AwVhEjTDPMQMsc9M9Cx9HyIJbknMLOEJNC8xpOR/3zy1RPbXXVWD8tM9Rcq3Kx0lesvKORZz2NFtVmnWJ2j2NLAnYsiJCd9tlzz7122XTnnfbb2dxUi96A1x044GDwnc0Zfwuu+OCLK274c4UkzvjkZj3+ldxkUY5AApt3noDlldF1zP/YBAyzuemcp4665wGBDlcDeCUA+zKzyx77Arfnvjnuy+C+u+uADXPXMsTHXvzxxid/PPC8OEAYmnLBPoz0ttMee+3YXx/958y/oqsDl4hel/jkjz9+Md17Rf3620/fvu3uxy97A+lPVT75ic2lJWLDWD7AE/97QQCT1qv3sU9+6ytGAxTIQL7FpiLJiCD/JggOYJxKXAPMIAA3KCp1MHB6H5wfCEcowgRoUIAc/F8L3CSrr/EiGAsc4QKhEcMZwpCG0DihClHIQxVeaYdA1KEQAWioD9pQhEesoRJTOMQe/k9ITQwiEzloQ/q9sIpKxOENt9iAKHpxgw76ohOnKED/LWJRGJrIIhfVWEUxSnGMPDQOGd+4wwME0I76COAC2MhHNPZhjWbk4xzd2MTeNBGPuBiAPg6wyEbiIlMiaEBKYrjHQOJQG5YE5BbpSMhByvGQiixNKBlpGlI+8h5a0OQZg2ECVfYRhoOMJRx36JxZ/k+UbMGjKEupyERi4pUzjGQmV9lGWXLSkxiMoy+ICcxmNsCWxvRi/VYzw2pa85rYvKYKt8nNbnrzm96c5h+G6UwudhKacBTnOLPJznYuEJzwjCc41blOctoTlug8JjTpiSZ3+lOb3LTj/wSqSHlycwQPeB4//8jMe2KRgwJNZDQJaCaFLlQge6ykJP/ZTo3iYbGgHx3oPC+6CZRQspwNNakwEMnSE5L0FRndaEwXqFGO0lSmG32pQmLK043e1KYz7KlO5dHTouKUo0YdKjmMalSk4jSmSh3HAqb61KpqtKZBtWpOo1oNpmoVq9dkKrWMEwIAOw=="
+ },
+ {
+ "name": "Biological Scan",
+ "description": "You attempt to scan for clues regarding the tree's nature. It appears to be a fully mature oak tree. \n\nApproximated height is 13 ft, 6.4 inches. \n\nSubject sees no sign of an outer coating or otherwise layer protecting it from the void of space.\n\nSubject's surface temperature is 293.7 kelvin, as though it were sitting indoors.",
+ "choices": [
+ {
+ "key": "choice 2",
+ "name": "Check Sensor Integrity.",
+ "exit_node": "Its Not You...",
+ "on_selection_effects": [
+ {
+ "effect_type": "Add",
+ "quality": "Confusion",
+ "value": 5
+ }
+ ],
+ "delay": 50,
+ "delay_message": "This can't be right."
+ },
+ {
+ "key": "choice 4",
+ "name": "Attempt to take sample.",
+ "exit_node": "Sample Taken",
+ "on_selection_effects": [
+ {
+ "effect_type": "Add",
+ "quality": "Confusion",
+ "value": 3
+ }
+ ],
+ "delay": 40,
+ "delay_message": "Snip snip."
+ },
+ {
+ "key": "choice 6",
+ "name": "Examine Tree Roots.",
+ "exit_node": "Examine Roots",
+ "delay": 10
+ },
+ {
+ "key": "choice 9",
+ "name": "Sequence Sample Radiation with background noise.",
+ "exit_node": "Background Analysis",
+ "requirements": [
+ {
+ "quality": "Sample",
+ "operator": ">=",
+ "value": 1
+ }
+ ],
+ "delay": 0,
+ "delay_message": "This can't be real."
+ },
+ {
+ "key": "choice 40",
+ "name": "Leave.",
+ "exit_node": "FAIL",
+ "delay": 0
+ }
+ ],
+ "image": null,
+ "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMQAAAAAAAC15h2QtxeAoxVykROizRpxjxIAcgAAWwAAgAAAUAAAZAAAZgC0tLTKysr///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/2AgjmRpnigqrMMqtCvhyvFs17hQuPva67ygTwgcGovA3a61BLaeryj0mapar9isNjCNylpfgWwsLpPPZqBst066le84fB5nRpvdvGDL7/v/JmBeaWiFhIeGbGqLio1ljm2CklKUA4CXmJmaAYidhp9mBmOiYqQEpqZlk3qbra6vsCOenqijtgIHCLG7vL29CQoNCsDCxMPBxw0MxsTLyMLCCwq+1LuVe9VZ0M/c297d4NvZ41vXeueU5N/r4e3o79jkvOb0UAe4+Pf6uMjS7P/TtAAcGKyeQXhT5ClcSKIdwYcHIyKMx7CiwocOwU3cWMmiR4YYQzqM+LGkSQXSUv/2y0jQH0qUJmNqoRSm5ixQbXLK2UmnJ886ToIilFltkk2cNw9B+umz6U87UOsRNXk0KdKrVrOSWWVwqlc+WHHWKnWqrKizZV+QGrA2yte31YDJPTZXrrMEzhbkPSYNWF+4gAFBeICJGTLDxVi2C5yNIxSQikVu48i4j8TLT1i2khwOM+bKVSQaeGLgQOnS+fIBwkiCszfPjqWAnn0ism1hsXO/oM279e3fuqmYeAChN++XKqP9BujP+EcXMKLkoFFm+o3qSH5oJ7L9SPfs3IlEHw/dhfNyLMpbX4+duvvw3uGDj08fCfn0+KVTPI9Ff/T37AHY3nXfFSifgfX9cJ//f/vxh95/1wkoYYQU5oDgfBh+t+B9DsJS4YABfiiDAWWQOGKJKJ6oYidcDdVhUVrFGFZWRl32IlEy0nJLWjyu1VYYrNxY2YxXjZUWW1+0FaSQDiaQ4z0y3OMXX3wxaSUKiWWZTF5c+sVASl8iB9OVbxFH3CVabmOMa9yQ6WYAbHL2Zh+UVRTnbV3NyUlwu120HEuw9WlloO+Mc+c3fCbEH6ES/Ybmn9AwWmdvnu1jaWoHpMBmFYdK+tmLiQqKCaTAebqRnh4d6o6pEqHqEan/sOqiqxbBumqoig42GK0WqUqQY7zCtZKvDgXL37AvEbvNAsaeJ6Zy0JKqErPNYpIj/xqOOKUtU9xu6+1OUekpCJFpLPXtud2mu21UTbhKLraPqCsvuvQ+FdQSqI57bbnxtlHvv/OCK5RsqO4Lr78BA6xwulDR+m4n5iYs8cJNVNyguwYzEi/FE3dsR7UpZJzIxh1z7FO4IJ8gMr860WuAEi/rEHMBM88s8ccpn/AwVhEjTDPMQMsc9M9Cx9HyIJbknMLOEJNC8xpOR/3zy1RPbXXVWD8tM9Rcq3Kx0lesvKORZz2NFtVmnWJ2j2NLAnYsiJCd9tlzz7122XTnnfbb2dxUi96A1x044GDwnc0Zfwuu+OCLK274c4UkzvjkZj3+ldxkUY5AApt3noDlldF1zP/YBAyzuemcp4665wGBDlcDeCUA+zKzyx77Arfnvjnuy+C+u+uADXPXMsTHXvzxxid/PPC8OEAYmnLBPoz0ttMee+3YXx/958y/oqsDl4hel/jkjz9+Md17Rf3620/fvu3uxy97A+lPVT75ic2lJWLDWD7AE/97QQCT1qv3sU9+6ytGAxTIQL7FpiLJiCD/JggOYJxKXAPMIAA3KCp1MHB6H5wfCEcowgRoUIAc/F8L3CSrr/EiGAsc4QKhEcMZwpCG0DihClHIQxVeaYdA1KEQAWioD9pQhEesoRJTOMQe/k9ITQwiEzloQ/q9sIpKxOENt9iAKHpxgw76ohOnKED/LWJRGJrIIhfVWEUxSnGMPDQOGd+4wwME0I76COAC2MhHNPZhjWbk4xzd2MTeNBGPuBiAPg6wyEbiIlMiaEBKYrjHQOJQG5YE5BbpSMhByvGQiixNKBlpGlI+8h5a0OQZg2ECVfYRhoOMJRx36JxZ/k+UbMGjKEupyERi4pUzjGQmV9lGWXLSkxiMoy+ICcxmNsCWxvRi/VYzw2pa85rYvKYKt8nNbnrzm96c5h+G6UwudhKacBTnOLPJznYuEJzwjCc41blOctoTlug8JjTpiSZ3+lOb3LTj/wSqSHlycwQPeB4//8jMe2KRgwJNZDQJaCaFLlQge6ykJP/ZTo3iYbGgHx3oPC+6CZRQspwNNakwEMnSE5L0FRndaEwXqFGO0lSmG32pQmLK043e1KYz7KlO5dHTouKUo0YdKjmMalSk4jSmSh3HAqb61KpqtKZBtWpOo1oNpmoVq9dkKrWMEwIAOw=="
+ },
+ {
+ "name": "Its Not You...",
+ "description": "After re-connection is established, your sensors appear fine. Tree has not moved in the slightest since last observed. Temperature has fluxuated 0.2 kelvin upwards, as expected of a plant under direct light.\nLets try again.",
+ "choices": [
+ {
+ "key": "choice 3",
+ "name": "Restart biological scan.",
+ "exit_node": "Biological Scan",
+ "delay": 25,
+ "delay_message": "God damnit."
+ }
+ ],
+ "image": null,
+ "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD////v7+/h4eEAAAAAAAAAAAAD/xi63P4wykmrvTjrzbv/YCiOZBkJaJqaLKOubSy7b23fODxPOb7/m4FASBRofEBeT1W6JU3DYaRIjQqfkCWKg1xoddjSQEgQlM/mdDkc0Fa+8PiWLSIM7Pj73RxOlVF/ITlKNXSGDXp5iiFoaBlqfpFyk12HMgSYmZkfmppmmJ8gjXwUf2lglqmqq6ytrq+wsbKztLW2t7i5um2Ug669uyBCKMNRc4Q9qXHBJlVUFMbRV6pfR04ONszQzlZRlm7IveLaimZ7eJAESUsfyVnX2hfqv/Nv4vfZ8RWJ/Hkdn6NGtRsFyEg4VLwK6UvVqROdgMcWSpxIsaLFixgzatzIsf+jR1gIP7YbN6uaSAn4wFGbdNJFsZcpFRqS09IBt2kW3CkzWdNmNyIYpIWkw9Nevgbwat2ccNPbTnbWjtKQWfGnVZwzoQaNqVXXkDFWGx3qeoIry2CJzJ05p6aPTpRmfSXV1a/u2jM7TuldA8LXO6kXFemh5ihn3Lc9A9h1ZaqxpMNkK9rl5+EMKIGM9g5FSjJjv4aVOwEc/Q8iXx6ODSo5ualOQ9Bs0qVJTLu27du4c+vezbu379/AgwsfTry48ePIkytfqHp5xhfLadby+1soMJDLbhchlqIYpVbXa14dz718NMBEz/ZsWsU8zMhY1CdmL+VE+/ObgWSvPR4rj/f/xqxUFG1fVfHIUgLCN58zR5ABySpwbAAdZ1TNMgZYF9YHjWmsDAgNeglNqFSBJJYiG14JUmcYiHNZWJcE6HD4FGIrVuiFjROxJeNYChoFWUS5lBPjOTO2iM2PKuki2F1qfdPjjUjSeMuSk82Uml4fRimlLVR2OUAYBGHpo5aV4OJll1iYRkqWhag4FY75WXhmlTOoedo/ZVKI40Jz+pOEnX2ZsqcCeVJ0piEQieJhiEx0RBkrd6J2IiQFVXqPbZjEYqdmll6Jz0avtUaCqEFtaiqnekmHUagOhSZapvJMeioanXa2KqukZoCrJoruCKNmCngKZGC7urprPRKq+QZBP2XFKRGunBwL6waZjIbiBInu9hoj0o5wraRiOadrsX1kK24HvBK25rnstuvuu/DGK++89NZr77345qvvvhYlAAA7"
+ },
+ {
+ "name": "Sample Taken",
+ "description": "You collect and project a small sample of tree bark off the plant. The instant that the bark is removed from the tree, as though it suddenly remembered what it was, the moisture content of the bark freezes over, and implodes into small microparticles of splinters.\nSmall radioactive signature detected.",
+ "choices": [
+ {
+ "key": "choice 5",
+ "name": "Well that was... unexpected.",
+ "exit_node": "Biological Scan",
+ "delay": 0,
+ "delay_message": "Maybe something else might work better.",
+ "on_selection_effects": [
+ {
+ "effect_type": "Add",
+ "quality": "Sample",
+ "value": 1
+ }
+ ]
+ }
+ ],
+ "image": null,
+ "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAABSLiiPVjtyRS9mOTFbNyYAAAAD/xi63P4wykmrvTjrzbv/YCiOZGmeaKqubOu+sDUQxTDbeK7vfF/3saCwcxPcCMckcqlM2pDPnnRKrUqH2IdAYDBwu+Bwl2Agm8sE8iy9Zrqbb2Z0bq3b74W8Xp+1bP+Af2KDhIVlh2eJaUtsi3CPcU43d5QDe5cFfSKBnJ2en50Ff6JboqYCBWiLq46tkK+RUJOTmJmatxyguqSovae/vsGirK2NjU21trjLQp+8wNDCwnmo1MnM2Nna29zd3t/g4eLj5OXm59o5Rjo/QOjvLaKwkrKylfdW8FleXImIBm0CxppXD4c9fAgT5tCn4Iuhh4fG/DNTjNHAi4/oKERYq/+cro8gPYXxR7EkK4EEUxbUOCVZHoabQoZ8NkqaKWI4BR7DGKcjTG4yaZaySRSatQLGfP5ciqHX0GhQpzGdSrWq1atYs2rdyrWr169gw4pVsc7G2LMLkM46SOkl2nc86W3E97aFgLh4Dc7dq6NuhC0TVVlUOY8l38N9szocREYiyYqEMdJZibjylW+AIRIiqUowyrwDJ+u1XMelsm6CNKtmHHiRZ8iuQGecVdklZpm4V3NWREznYNmhaeNRCg638eOBhrUWjPP3zshNDNuwzRW5dZrQmms3BhzSNb8SrIPCXvTudtjzMIEngVxo+ajDtKOkvt5u0Jrw3/s6yqd+Nk7/7uUn4FH+VaWfKAUmqOCCDDbo4IMQRijhhBRWaOGFGGao4YYcdujhhyCGKOKFRsgxy4jaBEeZOyi60J2JK1piS2ItcvDiaMIpVGMEv0GnIo46grgFbM/dKBppC004kXzo3fiGdJb51wUgiKTBnHNOzsYWkpd1xZpjrTHJnY+vQGlZOztMBUZmrO0mZo9Zwggkl/mkKc5qIy3n2nlExrnWnHROcRueYjSm55Wr+Ebmj2YeZpo4bBJqyG6Inqeon0duRF84kuJJKW98Nrkojlu2dYlHkXaq6qehNvfZqHI2+ihq4lGpKhisttpbbKNm6sN3t9Wam2q5Vtrqq5jesKk3jsI220mheuq665jJzoqqs9gGcqi0211KGLBUZYutciUZG6q3cREnlrjiPcZtTqIiAW597H5E07uuiqqehPXONIq57+6rYb81PWUTvmksuyHBTjUc1XnVmOLWjgFkG+CBNk1MsRb1kiegLxtf4KzHB4b8Qa0XA2OyfZ6QjODKywwlM8w012zzzTjnrPNWCQAAOw=="
+ },
+ {
+ "name": "Examine Roots",
+ "description": "All plant matter has to derive energy and moisture from someplace. Examining the oak tree's roots reveals that the roots present all appear to splay out, similar to how a normal tree would. However, those roots then proceed to double back in on itself. This might suggest that the tree is obtaining nutrients from... itself.",
+ "choices": [
+ {
+ "key": "choice 7",
+ "name": "That's fucking stupid.",
+ "exit_node": "Biological Scan",
+ "on_selection_effects": [
+ {
+ "effect_type": "Add",
+ "quality": "Confusion",
+ "value": {
+ "value_type": "random",
+ "low": 6,
+ "high": 10
+ }
+ }
+ ],
+ "delay": 0,
+ "delay_message": "What the hell kind of tree even IS this?"
+ },
+ {
+ "key": "choice 8",
+ "name": "Obtain biological sample from roots.",
+ "exit_node": "Sample Taken",
+ "delay": 10,
+ "delay_message": "This is why we hire botanists on-site."
+ }
+ ],
+ "image": null,
+ "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMQAAAAAAAC15h2QtxeAoxVykROizRpxjxIAcgAAWwAAgAAAUAAAZAAAZgC0tLTKysr///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/2AgjmRpnigqrMMqtCvhyvFs17hQuPva67ygTwgcGovA3a61BLaeryj0mapar9isNjCNylpfgWwsLpPPZqBst066le84fB5nRpvdvGDL7/v/JmBeaWiFhIeGbGqLio1ljm2CklKUA4CXmJmaAYidhp9mBmOiYqQEpqZlk3qbra6vsCOenqijtgIHCLG7vL29CQoNCsDCxMPBxw0MxsTLyMLCCwq+1LuVe9VZ0M/c297d4NvZ41vXeueU5N/r4e3o79jkvOb0UAe4+Pf6uMjS7P/TtAAcGKyeQXhT5ClcSKIdwYcHIyKMx7CiwocOwU3cWMmiR4YYQzqM+LGkSQXSUv/2y0jQH0qUJmNqoRSm5ixQbXLK2UmnJ886ToIilFltkk2cNw9B+umz6U87UOsRNXk0KdKrVrOSWWVwqlc+WHHWKnWqrKizZV+QGrA2yte31YDJPTZXrrMEzhbkPSYNWF+4gAFBeICJGTLDxVi2C5yNIxSQikVu48i4j8TLT1i2khwOM+bKVSQaeGLgQOnS+fIBwkiCszfPjqWAnn0ism1hsXO/oM279e3fuqmYeAChN++XKqP9BujP+EcXMKLkoFFm+o3qSH5oJ7L9SPfs3IlEHw/dhfNyLMpbX4+duvvw3uGDj08fCfn0+KVTPI9Ff/T37AHY3nXfFSifgfX9cJ//f/vxh95/1wkoYYQU5oDgfBh+t+B9DsJS4YABfiiDAWWQOGKJKJ6oYidcDdVhUVrFGFZWRl32IlEy0nJLWjyu1VYYrNxY2YxXjZUWW1+0FaSQDiaQ4z0y3OMXX3wxaSUKiWWZTF5c+sVASl8iB9OVbxFH3CVabmOMa9yQ6WYAbHL2Zh+UVRTnbV3NyUlwu120HEuw9WlloO+Mc+c3fCbEH6ES/Ybmn9AwWmdvnu1jaWoHpMBmFYdK+tmLiQqKCaTAebqRnh4d6o6pEqHqEan/sOqiqxbBumqoig42GK0WqUqQY7zCtZKvDgXL37AvEbvNAsaeJ6Zy0JKqErPNYpIj/xqOOKUtU9xu6+1OUekpCJFpLPXtud2mu21UTbhKLraPqCsvuvQ+FdQSqI57bbnxtlHvv/OCK5RsqO4Lr78BA6xwulDR+m4n5iYs8cJNVNyguwYzEi/FE3dsR7UpZJzIxh1z7FO4IJ8gMr860WuAEi/rEHMBM88s8ccpn/AwVhEjTDPMQMsc9M9Cx9HyIJbknMLOEJNC8xpOR/3zy1RPbXXVWD8tM9Rcq3Kx0lesvKORZz2NFtVmnWJ2j2NLAnYsiJCd9tlzz7122XTnnfbb2dxUi96A1x044GDwnc0Zfwuu+OCLK274c4UkzvjkZj3+ldxkUY5AApt3noDlldF1zP/YBAyzuemcp4665wGBDlcDeCUA+zKzyx77Arfnvjnuy+C+u+uADXPXMsTHXvzxxid/PPC8OEAYmnLBPoz0ttMee+3YXx/958y/oqsDl4hel/jkjz9+Md17Rf3620/fvu3uxy97A+lPVT75ic2lJWLDWD7AE/97QQCT1qv3sU9+6ytGAxTIQL7FpiLJiCD/JggOYJxKXAPMIAA3KCp1MHB6H5wfCEcowgRoUIAc/F8L3CSrr/EiGAsc4QKhEcMZwpCG0DihClHIQxVeaYdA1KEQAWioD9pQhEesoRJTOMQe/k9ITQwiEzloQ/q9sIpKxOENt9iAKHpxgw76ohOnKED/LWJRGJrIIhfVWEUxSnGMPDQOGd+4wwME0I76COAC2MhHNPZhjWbk4xzd2MTeNBGPuBiAPg6wyEbiIlMiaEBKYrjHQOJQG5YE5BbpSMhByvGQiixNKBlpGlI+8h5a0OQZg2ECVfYRhoOMJRx36JxZ/k+UbMGjKEupyERi4pUzjGQmV9lGWXLSkxiMoy+ICcxmNsCWxvRi/VYzw2pa85rYvKYKt8nNbnrzm96c5h+G6UwudhKacBTnOLPJznYuEJzwjCc41blOctoTlug8JjTpiSZ3+lOb3LTj/wSqSHlycwQPeB4//8jMe2KRgwJNZDQJaCaFLlQge6ykJP/ZTo3iYbGgHx3oPC+6CZRQspwNNakwEMnSE5L0FRndaEwXqFGO0lSmG32pQmLK043e1KYz7KlO5dHTouKUo0YdKjmMalSk4jSmSh3HAqb61KpqtKZBtWpOo1oNpmoVq9dkKrWMEwIAOw=="
+ },
+ {
+ "name": "Background Analysis",
+ "description": "You compare the radioactive energy bands of the sample collected earlier with that of the nearby solar enviroment.\nNothing.\nThere is nothing nearby that matches the passive signal of the tree, or the bark, or anything similar.\nThis is really starting to get on your nerves.",
+ "choices": [
+ {
+ "key": "choice 10",
+ "name": "Smash your desk in frustration.",
+ "exit_node": "FAIL",
+ "delay": 50,
+ "delay_message": "No amount of pay is worth dealing with magical plant juju."
+ },
+ {
+ "key": "choice 11",
+ "name": "Check every known energy spectroscopy database.",
+ "exit_node": "Sample Match Found",
+ "delay": 900,
+ "delay_message": "You NEED an answer. You DESERVE an answer."
+ }
+ ],
+ "image": null,
+ "on_enter_effects": [
+ {
+ "effect_type": "Add",
+ "quality": "Confusion",
+ "value": {
+ "value_type": "random",
+ "low": 3,
+ "high": 5
+ }
+ }
+ ],
+ "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD///9ZVlKsMjJpampGR0cAAAAD/xi63P4wykmFpTjrDa0XXCiOZGlqQ0qsazqIXyx9Z23feKayfP/WskgwRywqCsikcslsOpGpgGvQNDo8lYt1W4I+v2CvMhUuI0/YiZbL5nxdhkJ8Lq/T6eZ8HRmHUtuAgRp6T3B2SXdNfYeJc3CCkJEYjISVYZKRQ5gajZSdi0yboqM3nnWkqKmCpgaqrq9GBrKzs7AKaYG4tji0vbu/wCW6wZpqNMHIOAM9zDw/IzEgHcVt1KOWZQ1TU4LDV2vJOAVU2GZkY5VF4NPr4SRM53yI8/Lw9uVvBcLuknqGn4cqLQIYhwy/g0fwKdSDsCEGggtDOZwoAiLFi5sAYtwoqf/XIVjeOKrqRUukjZAmGVjDGC2lSyAts7R7GW5ZM2bPNERDGSAmzWA2b/pAc+yBT0ArVeXhsC2oj5wnefaU+pNBxDJNXUAqyq6qhKthyCUR+4QLVa5ej5AFO3ZJPGw3qE5N22DsWiUD6Tm5e/cqCbk96dZtQgZip3rjwIIa90fwqrBUDAfcQ0hyilaOIWG7zIoSYryd73DLrJntNlOIO2WVQ/raYrYKW/8CCNuJbH6S8aS7vSCpq9C8gxMMzns48dudj9/WqFw2yZKvfDc38Rxzc+kiq09f/nw7b+wNwV9HuwuwSvLeL14wjz49pm3Qds7sbd59jh1Co3CQP1+8/Rr/TgnVQnxHNVDgf0QEKCBUIRxIX3sIAiigMwzCAKF/cc1H1xQTVvjXhRCqE6IosU2Q1YkiajiViin+VhthWW0l1YhevQjjafrIKI0QLP5kI2GMBWkbG2fVx1FiP/oxRl9DEiEXCDsKhuSPazFpBg5P9miSkHmlpleXbbkVUVRRTkOakl7mRg9fsJmQ5Zl2DaDmJ4XVwZkZYHbpoU726eZCaID28RYYeRFEToQVeVaYLHIwOkugk70GqWiNIeoGQJc5qumclOU5qUGWXhraFNU1yumpdoAa6ganZkrLpJ2G5qido606CKoGwDErrqaaSlKttrIKq2r/DGvHr39aF2wIgsYaduKzqyUhhbLLjsArp3BVW0Oz3OpWlrY5dCsuKOByMS635QpyLaTEGenauZ2M5y4m696B4Lz0spLuRMnt25BH9vr7b3XUChwOwbIYfBDCBSscDMIOL0xwxO5ATPHB2kVHY7oTg7RxuR0rhyFFIYv8MUYZX5xMySoDk3LLD3dXbQIAOw=="
+ },
+ {
+ "name": "Sample Match Found",
+ "description": "After an extensive algorithm search on the controller end, you have a single match to this specific band and style of energy.\nThe problem, is that the source of said radiation is coming not only from Space Station 13, no.\nIt's coming from the Space Station 13 Research Department.\nWhat the fuck?",
+ "choices": [
+ {
+ "key": "choice 12",
+ "name": "Something must be wrong with the drone.",
+ "exit_node": "Its Not You...",
+ "on_selection_effects": [
+ {
+ "effect_type": "Add",
+ "quality": "Confusion",
+ "value": {
+ "value_type": "random",
+ "low": 6,
+ "high": 10
+ }
+ }
+ ],
+ "delay": 30,
+ "delay_message": "Lousy piece of junk must be scanning the station instead of the target."
+ },
+ {
+ "key": "choice 13",
+ "name": "Perhaps that sample was tainted. Collect a new sample.",
+ "exit_node": "Sample Taken",
+ "delay": 60,
+ "delay_message": "Lets try again, but carefully."
+ },
+ {
+ "key": "choice 14",
+ "name": "Remember the Christmas Party.",
+ "exit_node": "The Christmas Party",
+ "requirements": [
+ {
+ "quality": "Confusion",
+ "operator": "<=",
+ "value": 25
+ }
+ ],
+ "delay": 100,
+ "delay_message": "Wait a gosh darn fucking second."
+ }
+ ],
+ "image": null,
+ "on_enter_effects": [
+ {
+ "effect_type": "Add",
+ "quality": "Confusion",
+ "value": 10
+ }
+ ],
+ "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD////v7+/h4eEAAAAAAAAAAAAD/xi63P4wykmrvTjrzbv/YCiOZBkJaJqaLKOubSy7b23fODxPOb7/m4FASBRofEBeT1W6JU3DYaRIjQqfkCWKg1xoddjSQEgQlM/mdDkc0Fa+8PiWLSIM7Pj73RxOlVF/ITlKNXSGDXp5iiFoaBlqfpFyk12HMgSYmZkfmppmmJ8gjXwUf2lglqmqq6ytrq+wsbKztLW2t7i5um2Ug669uyBCKMNRc4Q9qXHBJlVUFMbRV6pfR04ONszQzlZRlm7IveLaimZ7eJAESUsfyVnX2hfqv/Nv4vfZ8RWJ/Hkdn6NGtRsFyEg4VLwK6UvVqROdgMcWSpxIsaLFixgzatzIsf+jR1gIP7YbN6uaSAn4wFGbdNJFsZcpFRqS09IBt2kW3CkzWdNmNyIYpIWkw9Nevgbwat2ccNPbTnbWjtKQWfGnVZwzoQaNqVXXkDFWGx3qeoIry2CJzJ05p6aPTpRmfSXV1a/u2jM7TuldA8LXO6kXFemh5ihn3Lc9A9h1ZaqxpMNkK9rl5+EMKIGM9g5FSjJjv4aVOwEc/Q8iXx6ODSo5ualOQ9Bs0qVJTLu27du4c+vezbu379/AgwsfTry48ePIkytfqHp5xhfLadby+1soMJDLbhchlqIYpVbXa14dz718NMBEz/ZsWsU8zMhY1CdmL+VE+/ObgWSvPR4rj/f/xqxUFG1fVfHIUgLCN58zR5ABySpwbAAdZ1TNMgZYF9YHjWmsDAgNeglNqFSBJJYiG14JUmcYiHNZWJcE6HD4FGIrVuiFjROxJeNYChoFWUS5lBPjOTO2iM2PKuki2F1qfdPjjUjSeMuSk82Uml4fRimlLVR2OUAYBGHpo5aV4OJll1iYRkqWhag4FY75WXhmlTOoedo/ZVKI40Jz+pOEnX2ZsqcCeVJ0piEQieJhiEx0RBkrd6J2IiQFVXqPbZjEYqdmll6Jz0avtUaCqEFtaiqnekmHUagOhSZapvJMeioanXa2KqukZoCrJoruCKNmCngKZGC7urprPRKq+QZBP2XFKRGunBwL6waZjIbiBInu9hoj0o5wraRiOadrsX1kK24HvBK25rnstuvuu/DGK++89NZr77345qvvvhYlAAA7"
+ },
+ {
+ "name": "The Christmas Party",
+ "description": "Hold on. Last Christmas, the Research Director was incredibly hammered. He made a big mention that his brand new festivus pole was actually some kind of astrological... something something. You can't remember the whole details, because you were smashed as well. However, briefly, the RD did keep that festivus pole for awhile, he might even still have it somewhere.\nMaybe...?",
+ "choices": [
+ {
+ "key": "choice 15",
+ "name": "Wait a minute, was that a god damn...",
+ "exit_node": "Rod.",
+ "delay": 100,
+ "delay_message": "Immovable Rod?"
+ }
+ ],
+ "image": null,
+ "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD/AACmAAD///+mpqYAAAAAAAAD/xi63P4wykmrvTjrzbv/YCiOZGmejKCubOu6aCzP4WvfeD4IQ+//Pppw+MkZj6udkgdsOp/EqFSBrNqWwQ9hy+16v9ypeGM9YpnAE3hNKLTfhbG8kuTZz/j7/fmb+/8TbIJefIVNgIiJGgWMjY6PkJGRipSVlpeYmZqbnJ2en6ChoqOkpRplqDdYpqyprnpKhnyslq9leFkYg2u0QrZmaLkgu8S9JDg7Ksl2yrB7UDJw0m6QxiFfedk9wbKH1tbEW9TT05Lmjd/pJpPq7e7v8PHy8/T19vf4+fr7Kb9W/Jn8pcLiBKAcgVZwdethkAZCJAoXFmx47KEOWLMeAAlHMf+DRVXctIT70jHCxxYEhXkYKajkgpMRGZZgKY5LHJcJ6zTTNtHEm5rjgsK5WZKZs2xHn2WccY6RSwdJkaaUOOApoHDbqFK16ofmF6Fg20Aa8IhrpbBBm6plZ7aTIwhr0bWdS7eu3bt48+rdy7ev37+AAwseTLiw4cOI0/1LfPAkC8YlHINUApmD5MncVFZ+cPmK0qWbX3Z2MbVbaCqjd37eCjk1i9JaZR5OHTN2z8Gua9v2wavvaNjeKgygqbcz8KocvBLAexn4MOVb5jZfjVwk9DBW/S3bTn3E9S5cUXFvphqaCOhBs7/WGbU96PNr0EpTT96o1Kjv4ZOT/xbn/f921AWnBlhNWQXggZndFkNcZv2X1YOxsCZENXdJBWGCWp2mQRc+YLibIRpaQMyHEoVYgVfDcUFiHyYGopxQTgwFYosugsFfOXGZQyMGN+boI1E78vjjkHIF+QGRahkZxVpKNunkk1BGKeWUVFZp5ZVYZqnllogkAAA7"
+ },
+ {
+ "name": "Rod.",
+ "description": "You cross reference your documentation. Sure enough, the \"festivus rod\" collected was actually an immovable rod.\nEnergy detected from the rod is the exact same coming off of the tree, as well. It's all making sense now. The Immovable rod is producing a kind of unique blackbody radiation that is providing sample heat and light for what is effectively an internal cold fusion process, and producing just enough of that radiation to create a kind of micro-enviromental bubble around the biosignature of the tree.\n\nThis would make the first time an immovable rod would exist in tandem with a biological source. You jot down some research notes on your findings, which could easily produce some kind of experimental tech, no doubt.",
+ "choices": [
+ {
+ "key": "choice 16",
+ "name": "Snap a photo",
+ "exit_node": "Epilogue.",
+ "delay": 40,
+ "delay_message": "You could easily win an award for these findings!"
+ }
+ ],
+ "image": "default"
+ },
+ {
+ "name": "Epilogue.",
+ "description": "You take a photo with the onboard camera on the drone. Suddenly, the immovable rod inside the tree explodes out of the wooden biological shell, and produces a blank, blurry photo.\nWhat the fuck?",
+ "choices": [
+ {
+ "key": "choice 17",
+ "name": "God damnit.",
+ "exit_node": "WIN",
+ "delay": 10,
+ "delay_message": "Some things were just not meant for man to know."
+ }
+ ],
+ "image": "default",
+ "on_enter_effects": [
+ {
+ "effect_type": "Set",
+ "quality": "Confusion",
+ "value": 9999
+ }
+ ]
+ },
+ {
+ "name": "What is wrong with this tree?",
+ "description": "This is ridiculous. Nothing about this dumbass tree makes sense. It makes no sense, it's just sitting there, living and making a MOCKERY of all of science!\nYou didn't get your degree in advanced plasma-physics for this!",
+ "choices": [
+ {
+ "key": "choice 18",
+ "name": "The world can never know about this dumbass stupid plant.",
+ "exit_node": "FAIL_DEATH",
+ "delay": 60,
+ "delay_message": "Activating drone self-destruct."
+ },
+ {
+ "key": "choice 19",
+ "name": "Take a moment to calm down.",
+ "exit_node": "Biological Scan",
+ "on_selection_effects": [
+ {
+ "effect_type": "Add",
+ "quality": "Confusion",
+ "value": {
+ "value_type": "random",
+ "low": -3,
+ "high": -5
+ }
+ }
+ ],
+ "delay": 20,
+ "delay_message": "Breathe."
+ }
+ ],
+ "image": "default"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/modules/explorer_drone/exodrone.dm b/code/modules/explorer_drone/exodrone.dm
index 72cf09bd81b..5c73f5755df 100644
--- a/code/modules/explorer_drone/exodrone.dm
+++ b/code/modules/explorer_drone/exodrone.dm
@@ -5,7 +5,7 @@
// Fuel types and travel time per unit of distance on that fuel.
#define FUEL_BASIC "basic"
-#define BASIC_FUEL_TIME_COST 300
+#define BASIC_FUEL_TIME_COST 250
#define FUEL_ADVANCED "advanced"
#define ADVANCED_FUEL_TIME_COST 200
@@ -334,9 +334,9 @@ GLOBAL_LIST_EMPTY(exodrone_launchers)
drone_log("Sustained [amount] damage.")
/obj/item/exodrone/proc/drone_log(message)
- drone_log.Insert(1,message)
if(length(drone_log) > EXODRONE_LOG_SIZE)
- drone_log.Cut(EXODRONE_LOG_SIZE)
+ drone_log = list()
+ drone_log.Insert(1,message)
/obj/item/exodrone/proc/has_tool(tool_type)
return tools.Find(tool_type)
@@ -354,6 +354,11 @@ GLOBAL_LIST_EMPTY(exodrone_launchers)
. = ..()
GLOB.exodrone_launchers += src
+/obj/machinery/exodrone_launcher/examine(user)
+ . = ..()
+ if(fuel_canister)
+ . += span_notice("You can remove the [fuel_canister] with a prying tool.")
+
/obj/machinery/exodrone_launcher/attackby(obj/item/weapon, mob/living/user, params)
if(istype(weapon, /obj/item/fuel_pellet))
if(fuel_canister)
@@ -374,7 +379,7 @@ GLOBAL_LIST_EMPTY(exodrone_launchers)
if(!fuel_canister)
return
- to_chat(user, span_notice("You remove the [fuel_canister] from the [src]."))
+ to_chat(user, span_notice("You remove [fuel_canister] from [src]."))
fuel_canister.forceMove(drop_location())
fuel_canister = null
update_icon()
diff --git a/code/modules/explorer_drone/scanner_array.dm b/code/modules/explorer_drone/scanner_array.dm
index e5b5f7a026c..7f019b0d43c 100644
--- a/code/modules/explorer_drone/scanner_array.dm
+++ b/code/modules/explorer_drone/scanner_array.dm
@@ -14,9 +14,9 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions())
#define MAX_SCAN_DISTANCE 10
-#define WIDE_SCAN_COST(BAND, SCAN_POWER) (((BAND*BAND)/(SCAN_POWER))*2*60*10)
-#define BASE_POINT_SCAN_TIME (5 MINUTES)
-#define BASE_DEEP_SCAN_TIME (5 MINUTES)
+#define WIDE_SCAN_COST(BAND, SCAN_POWER) (min(((BAND*BAND)/(SCAN_POWER))*2*60*10, 10 MINUTES))
+#define BASE_POINT_SCAN_TIME (2 MINUTES)
+#define BASE_DEEP_SCAN_TIME (3 MINUTES)
/// Represents scan in progress, only one globally for now, todo later split per z or allow partial dish swarm usage
/datum/exoscan
@@ -35,7 +35,7 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions())
var/scan_time = 0
switch(scan_type)
if(EXOSCAN_WIDE)
- scan_power = length(GLOB.exoscanner_controller.tracked_dishes)
+ scan_power = GLOB.exoscanner_controller.calculate_scan_power()
scan_time = WIDE_SCAN_COST(GLOB.exoscanner_controller.wide_scan_band,scan_power)
if(EXOSCAN_POINT)
scan_power = GLOB.exoscanner_controller.get_scan_power(target)
@@ -76,7 +76,8 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions())
deltimer(scan_timer)
/obj/machinery/computer/exoscanner_control
- name = "Scanner Array Control Console"
+ name = "scanner array control console"
+ desc = "Controls scanner arrays to initiate scans for exodrones."
circuit = /obj/item/circuitboard/computer/exoscanner_console
/// If scan was interrupted show a popup until dismissed.
var/failed_popup = FALSE
@@ -105,7 +106,7 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions())
condition_descriptions += condition.description
.["scan_conditions"] = condition_descriptions
else
- .["scan_power"] = scan_power = length(GLOB.exoscanner_controller.tracked_dishes)
+ .["scan_power"] = scan_power = GLOB.exoscanner_controller.calculate_scan_power()
.["wide_scan_eta"] = scan_power > 0 ? WIDE_SCAN_COST(GLOB.exoscanner_controller.wide_scan_band,scan_power) : 0
.["possible_sites"] = build_exploration_site_ui_data()
.["scan_conditions"] = null
@@ -196,11 +197,35 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions())
icon = 'icons/obj/exploration.dmi'
icon_state = "scanner_off"
desc = "A sophisticated scanning array. Easily influenced by its environment."
+ circuit = /obj/item/circuitboard/machine/exoscanner
+ ///the scan power of this array to supply to scanner_controller
+ var/scan_power = 1
/obj/machinery/exoscanner/Initialize(mapload)
. = ..()
RegisterSignals(GLOB.exoscanner_controller,list(COMSIG_EXOSCAN_STARTED,COMSIG_EXOSCAN_FINISHED), PROC_REF(scan_change))
update_readiness()
+ RefreshParts()
+
+/obj/machinery/exoscanner/RefreshParts()
+ . = ..()
+ var/power = 1
+
+ for(var/datum/stock_part/scanning_module/scanning_module in component_parts)
+ power += (scanning_module.tier - 1) / 12
+ scan_power = power
+ GLOB.exoscanner_controller.update_scan_power()
+
+/obj/machinery/exoscanner/screwdriver_act(mob/user, obj/item/tool)
+ . = ..()
+ if(!.)
+ . = default_deconstruction_screwdriver(user, "scanner_open", "scanner_off", tool)
+ update_readiness()
+
+/obj/machinery/exoscanner/crowbar_act(mob/user, obj/item/tool)
+ ..()
+ if(default_deconstruction_crowbar(tool))
+ return TRUE
/obj/machinery/exoscanner/proc/scan_change()
SIGNAL_HANDLER
@@ -215,7 +240,7 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions())
GLOB.exoscanner_controller.deactivate_scanner(src)
/obj/machinery/exoscanner/proc/is_ready()
- return anchored && is_operational
+ return anchored && is_operational && !panel_open
/obj/machinery/exoscanner/proc/update_readiness()
if(is_ready())
@@ -302,7 +327,7 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions())
/datum/scanner_controller/proc/calculate_scan_power(conditions)
. = 0
for(var/obj/machinery/exoscanner/dish in tracked_dishes)
- var/effective_power = 1
+ var/effective_power = dish.scan_power
for(var/datum/scan_condition/condition in conditions)
effective_power *= condition.check_dish(dish)
if(!effective_power) //Don't bother continuing if it's zero
diff --git a/code/modules/food_and_drinks/restaurant/_venue.dm b/code/modules/food_and_drinks/restaurant/_venue.dm
index a73cb6b4e35..f8e171948a6 100644
--- a/code/modules/food_and_drinks/restaurant/_venue.dm
+++ b/code/modules/food_and_drinks/restaurant/_venue.dm
@@ -60,10 +60,10 @@
if (initial(customer_type.is_unique))
customer_types -= customer_type
- var/mob/living/simple_animal/robot_customer/new_customer = new /mob/living/simple_animal/robot_customer(get_turf(restaurant_portal), customer_type, src)
+ var/mob/living/basic/robot_customer/new_customer = new /mob/living/basic/robot_customer(get_turf(restaurant_portal), customer_type, src)
current_visitors += new_customer
-/datum/venue/proc/order_food(mob/living/simple_animal/robot_customer/customer_pawn, datum/customer_data/customer_data)
+/datum/venue/proc/order_food(mob/living/basic/robot_customer/customer_pawn, datum/customer_data/customer_data)
var/order = pick_weight(customer_data.orderable_objects[venue_type])
var/list/order_args // Only for custom orders - arguments passed into New
var/image/food_image
@@ -113,7 +113,7 @@
return "broken venue pls call a coder"
///Effects for when a customer receives their order at this venue
-/datum/venue/proc/on_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item)
+/datum/venue/proc/on_get_order(mob/living/basic/robot_customer/customer_pawn, obj/item/order_item)
SHOULD_CALL_PARENT(TRUE)
// This is an item typepath, a reagent typepath, or a custom order datum instance.
@@ -152,7 +152,7 @@
open = FALSE
restaurant_portal.update_icon()
STOP_PROCESSING(SSobj, src)
- for(var/mob/living/simple_animal/robot_customer as anything in current_visitors)
+ for(var/mob/living/basic/robot_customer as anything in current_visitors)
robot_customer.ai_controller.set_blackboard_key(BB_CUSTOMER_LEAVING, TRUE) //LEAVEEEEEE
/obj/machinery/restaurant_portal
diff --git a/code/modules/food_and_drinks/restaurant/custom_order.dm b/code/modules/food_and_drinks/restaurant/custom_order.dm
index c74b4883c19..d87797b2578 100644
--- a/code/modules/food_and_drinks/restaurant/custom_order.dm
+++ b/code/modules/food_and_drinks/restaurant/custom_order.dm
@@ -34,7 +34,7 @@
* Return [TRANSACTION_SUCCESS] to denote the order went through successfully (Not generally necessary to include here)
* Return [TRANSACTION_HANDLED] to not do any further handling of the order by the
*/
-/datum/custom_order/proc/handle_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item)
+/datum/custom_order/proc/handle_get_order(mob/living/basic/robot_customer/customer_pawn, obj/item/order_item)
return NONE
/datum/custom_order/moth_clothing
@@ -153,7 +153,7 @@
food_image.add_overlay(drink_image)
return food_image
-/datum/custom_order/reagent/handle_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item)
+/datum/custom_order/reagent/handle_get_order(mob/living/basic/robot_customer/customer_pawn, obj/item/order_item)
. = TRANSACTION_HANDLED
for(var/datum/reagent/reagent as anything in order_item.reagents?.reagent_list)
@@ -184,7 +184,7 @@
/datum/custom_order/reagent/drink
container_needed = /obj/item/reagent_containers/cup/glass/drinkingglass
-/datum/custom_order/reagent/drink/handle_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item)
+/datum/custom_order/reagent/drink/handle_get_order(mob/living/basic/robot_customer/customer_pawn, obj/item/order_item)
customer_pawn.visible_message(
span_danger("[customer_pawn] slurps up [order_item] in one go!"),
span_danger("You slurp up [order_item] in one go."),
@@ -210,7 +210,7 @@
/datum/custom_order/reagent/soup/get_order_line(datum/venue/our_venue)
return "I'll take a [picked_serving] of [initial(reagent_type.name)]"
-/datum/custom_order/reagent/soup/handle_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item)
+/datum/custom_order/reagent/soup/handle_get_order(mob/living/basic/robot_customer/customer_pawn, obj/item/order_item)
customer_pawn.visible_message(
span_danger("[customer_pawn] pours [order_item] right down [customer_pawn.p_their()] hatch!"),
span_danger("You pour [order_item] down your hatch in one go."),
diff --git a/code/modules/food_and_drinks/restaurant/customers/_customer.dm b/code/modules/food_and_drinks/restaurant/customers/_customer.dm
index c5a7f809586..3f13b526056 100644
--- a/code/modules/food_and_drinks/restaurant/customers/_customer.dm
+++ b/code/modules/food_and_drinks/restaurant/customers/_customer.dm
@@ -52,10 +52,10 @@
/datum/customer_data/proc/can_use(datum/venue/venue)
return TRUE
-/datum/customer_data/proc/get_overlays(mob/living/simple_animal/robot_customer/customer)
+/datum/customer_data/proc/get_overlays(mob/living/basic/robot_customer/customer)
return
-/datum/customer_data/proc/get_underlays(mob/living/simple_animal/robot_customer/customer)
+/datum/customer_data/proc/get_underlays(mob/living/basic/robot_customer/customer)
return
/datum/customer_data/american
@@ -177,7 +177,7 @@
),
)
-/datum/customer_data/french/get_overlays(mob/living/simple_animal/robot_customer/customer)
+/datum/customer_data/french/get_overlays(mob/living/basic/robot_customer/customer)
if(customer.ai_controller.blackboard[BB_CUSTOMER_LEAVING])
var/mutable_appearance/flag = mutable_appearance(customer.icon, "french_flag")
flag.appearance_flags = RESET_COLOR
@@ -224,7 +224,7 @@
),
)
-/datum/customer_data/japanese/get_overlays(mob/living/simple_animal/robot_customer/customer)
+/datum/customer_data/japanese/get_overlays(mob/living/basic/robot_customer/customer)
//leaving and eaten
if(type == /datum/customer_data/japanese && customer.ai_controller.blackboard[BB_CUSTOMER_LEAVING] && customer.ai_controller.blackboard[BB_CUSTOMER_EATING])
var/mutable_appearance/you_won_my_heart = mutable_appearance('icons/effects/effects.dmi', "love_hearts")
@@ -303,13 +303,13 @@
return FALSE
return TRUE
-/datum/customer_data/moth/proc/get_wings(mob/living/simple_animal/robot_customer/customer)
+/datum/customer_data/moth/proc/get_wings(mob/living/basic/robot_customer/customer)
var/customer_ref = WEAKREF(customer)
if (!LAZYACCESS(wings_chosen, customer_ref))
LAZYSET(wings_chosen, customer_ref, pick(GLOB.sprite_accessories["wings"]))
return wings_chosen[customer_ref]
-/datum/customer_data/moth/get_underlays(mob/living/simple_animal/robot_customer/customer)
+/datum/customer_data/moth/get_underlays(mob/living/basic/robot_customer/customer)
var/list/underlays = list()
var/datum/sprite_accessory/moth_wings/wings = get_wings(customer)
@@ -320,7 +320,7 @@
return underlays
-/datum/customer_data/moth/get_overlays(mob/living/simple_animal/robot_customer/customer)
+/datum/customer_data/moth/get_overlays(mob/living/basic/robot_customer/customer)
var/list/overlays = list()
var/datum/sprite_accessory/moth_wings/wings = get_wings(customer)
diff --git a/code/modules/food_and_drinks/restaurant/generic_venues.dm b/code/modules/food_and_drinks/restaurant/generic_venues.dm
index 19f1ff61323..9e9b0a6d0e3 100644
--- a/code/modules/food_and_drinks/restaurant/generic_venues.dm
+++ b/code/modules/food_and_drinks/restaurant/generic_venues.dm
@@ -42,7 +42,7 @@
var/obj/item/object_to_order = order
return "I'll take \a [initial(object_to_order.name)]"
-/datum/venue/restaurant/on_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item)
+/datum/venue/restaurant/on_get_order(mob/living/basic/robot_customer/customer_pawn, obj/item/order_item)
var/transaction_result = ..()
if((transaction_result & TRANSACTION_HANDLED) || !(transaction_result & TRANSACTION_SUCCESS))
return
diff --git a/code/modules/hydroponics/grown/replicapod.dm b/code/modules/hydroponics/grown/replicapod.dm
index 8e5dda5a7fa..c1fd02bf9f0 100644
--- a/code/modules/hydroponics/grown/replicapod.dm
+++ b/code/modules/hydroponics/grown/replicapod.dm
@@ -37,7 +37,7 @@
plant_icon_offset = 2
species = "replicapod"
plantname = "Replica Pod"
- product = /mob/living/carbon/human //verrry special -- Urist
+ product = null // the human mob is spawned in harvest()
lifespan = 50
endurance = 8
maturation = 10
diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm
index a3804c9262f..04b0edf44bb 100644
--- a/code/modules/hydroponics/seed_extractor.dm
+++ b/code/modules/hydroponics/seed_extractor.dm
@@ -13,46 +13,33 @@
* * user - checks if we can remove the object from the inventory
* *
*/
-/proc/seedify(obj/item/O, t_max, obj/machinery/seed_extractor/extractor, mob/living/user)
- var/t_amount = 0
+/proc/seedify(obj/item/object, t_max, obj/machinery/seed_extractor/extractor, mob/living/user)
+ //try to get the seed from this item
+ var/obj/item/seeds/seed = object.get_plant_seed()
+ if(isnull(seed))
+ return null
+
+ //generate a random multiplier if value is not specified
var/list/seeds = list()
if(t_max == -1)
if(extractor)
t_max = rand(1,4) * extractor.seed_multiplier
else
t_max = rand(1,4)
-
- var/seedloc = O.loc
+ //drop location for the newly generated seeds
+ var/seedloc = object.loc
if(extractor)
seedloc = extractor.loc
- if(istype(O, /obj/item/food/grown/))
- var/obj/item/food/grown/F = O
- if(F.seed)
- if(user && !user.temporarilyRemoveItemFromInventory(O)) //couldn't drop the item
- return
- while(t_amount < t_max)
- var/obj/item/seeds/t_prod = F.seed.Copy()
- seeds.Add(t_prod)
- t_prod.forceMove(seedloc)
- t_amount++
- qdel(O)
- return seeds
-
- else if(istype(O, /obj/item/grown))
- var/obj/item/grown/F = O
- if(F.seed)
- if(user && !user.temporarilyRemoveItemFromInventory(O))
- return
- while(t_amount < t_max)
- var/obj/item/seeds/t_prod = F.seed.Copy()
- t_prod.forceMove(seedloc)
- t_amount++
- qdel(O)
- return 1
-
- return 0
-
+ //multiply the seeds and delete the item
+ if(user && !user.temporarilyRemoveItemFromInventory(object)) //couldn't drop the item
+ return null
+ for(var/_ in 0 to t_max)
+ var/obj/item/seeds/t_prod = seed.Copy()
+ seeds.Add(t_prod)
+ t_prod.forceMove(seedloc)
+ qdel(object)
+ return seeds
/obj/machinery/seed_extractor
name = "seed extractor"
@@ -80,6 +67,7 @@
if(held_item?.get_plant_seed())
context[SCREENTIP_CONTEXT_LMB] = "Make seeds"
+ context[SCREENTIP_CONTEXT_RMB] = "Make & Store seeds"
return CONTEXTUAL_SCREENTIP_SET
if(istype(held_item, /obj/item/storage/bag/plants) && (locate(/obj/item/seeds) in held_item.contents))
@@ -135,7 +123,17 @@
return TRUE
- if(seedify(attacking_item, -1, src, user))
+ var/list/generated_seeds = seedify(attacking_item, -1, src, user)
+ if(!isnull(generated_seeds))
+ if(LAZYACCESS(params2list(params), RIGHT_CLICK))
+ //find all seeds lying on the turf and add them to the machine
+ for(var/obj/item/seeds/seed as anything in generated_seeds)
+ //machine is full
+ if(contents.len >= max_seeds)
+ to_chat(user, span_warning("[src] is full."))
+ break
+ //add seed to machine. second argument is null which means just force move into the machine
+ add_seed(seed)
to_chat(user, span_notice("You extract some seeds."))
return TRUE
@@ -176,23 +174,16 @@
* needed to go to the ui handler
*
* to_add - what seed are we adding?
- * taking_from - where are we taking the seed from? A mob, a bag, etc?
- * user - who is inserting the seed?
+ * taking_from - where are we taking the seed from? A mob, a bag, etc? If null its means its just laying on the turf so force move it in
**/
/obj/machinery/seed_extractor/proc/add_seed(obj/item/seeds/to_add, atom/taking_from)
- if(ismob(taking_from))
- var/mob/mob_loc = taking_from
- if(!mob_loc.transferItemToLoc(to_add, src))
- return FALSE
-
- else if(!taking_from.atom_storage?.attempt_remove(to_add, src, silent = TRUE))
- return FALSE
-
var/seed_id = generate_seed_hash(to_add)
+ var/list/seed_data
+ var/has_seed_data // so we remember to add a seed obj weakref to piles[seed_id] at the end of the proc. That way if some reason we runtime in this proc it won't incorrectly add data to the list
if(piles[seed_id])
- piles[seed_id]["refs"] += WEAKREF(to_add)
+ has_seed_data = TRUE
else
- var/list/seed_data = list()
+ seed_data = list()
seed_data["icon"] = sanitize_css_class_name("[initial(to_add.icon)][initial(to_add.icon_state)]")
seed_data["name"] = capitalize(replacetext(to_add.name,"pack of ", ""));
seed_data["lifespan"] = to_add.lifespan
@@ -216,8 +207,8 @@
seed_data["mutatelist"] = list()
for(var/obj/item/seeds/mutant as anything in to_add.mutatelist)
seed_data["mutatelist"] += initial(mutant.plantname)
- var/obj/item/food/grown/product = new to_add.product
- if(product)
+ if(to_add.product)
+ var/obj/item/food/grown/product = new to_add.product
var/datum/reagent/product_distill_reagent = product.distill_reagent
seed_data["distill_reagent"] = initial(product_distill_reagent.name)
var/datum/reagent/product_juice_typepath = product.juice_typepath
@@ -225,8 +216,25 @@
seed_data["grind_results"] = list()
for(var/datum/reagent/reagent as anything in product.grind_results)
seed_data["grind_results"] += initial(reagent.name)
- qdel(product)
+ qdel(product)
+
+ if(!isnull(taking_from))
+ if(ismob(taking_from))
+ var/mob/mob_loc = taking_from
+ if(!mob_loc.transferItemToLoc(to_add, src))
+ return FALSE
+
+ else if(!taking_from.atom_storage?.attempt_remove(to_add, src, silent = TRUE))
+ return FALSE
+ else
+ to_add.forceMove(src)
+
+ // do this at the end, in case any of the previous steps failed
+ if(has_seed_data)
+ piles[seed_id]["refs"] += WEAKREF(to_add)
+ else
piles[seed_id] = seed_data
+
return TRUE
/obj/machinery/seed_extractor/ui_state(mob/user)
diff --git a/code/modules/meteors/meteor_waves.dm b/code/modules/meteors/meteor_waves.dm
index 4235c186a94..7d832d53713 100644
--- a/code/modules/meteors/meteor_waves.dm
+++ b/code/modules/meteors/meteor_waves.dm
@@ -26,4 +26,4 @@ GLOBAL_LIST_INIT(meteors_stray, list(/obj/effect/meteor/medium=15, /obj/effect/m
GLOBAL_LIST_INIT(meteors_sandstorm, list(/obj/effect/meteor/sand=45, /obj/effect/meteor/dust=5)) //for sandstorm event
-GLOBAL_LIST_INIT(meteorsSPOOKY, list(/obj/effect/meteor/pumpkin))
+GLOBAL_LIST_INIT(meteorsSPOOKY, list(/obj/effect/meteor/pumpkin=1))
diff --git a/code/modules/mining/equipment/monster_organs/regenerative_core.dm b/code/modules/mining/equipment/monster_organs/regenerative_core.dm
index cb224438c00..98758d5a369 100644
--- a/code/modules/mining/equipment/monster_organs/regenerative_core.dm
+++ b/code/modules/mining/equipment/monster_organs/regenerative_core.dm
@@ -36,7 +36,7 @@
/// Log applications and apply moodlet.
/obj/item/organ/internal/monster_core/regenerative_core/apply_to(mob/living/target, mob/user)
- target.add_mood_event("regenerative core", /datum/mood_event/healsbadman)
+ target.add_mood_event(MOOD_CATEGORY_LEGION_CORE, /datum/mood_event/healsbadman)
if (target != user)
target.visible_message(span_notice("[user] forces [target] to apply [src]... Black tendrils entangle and reinforce [target.p_them()]!"))
SSblackbox.record_feedback("nested tally", "hivelord_core", 1, list("[type]", "used", "other"))
diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm
index e7199e59938..20a436dc5c6 100644
--- a/code/modules/mining/fulton.dm
+++ b/code/modules/mining/fulton.dm
@@ -144,7 +144,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons)
icon_state = "folded_extraction"
/obj/item/fulton_core/attack_self(mob/user)
- if(do_after(user,15,target = user) && !QDELETED(src))
+ if(do_after(user, 1.5 SECONDS, target = user) && !QDELETED(src))
new /obj/structure/extraction_point(get_turf(user))
playsound(src, 'sound/items/deconstruct.ogg', vol = 50, vary = TRUE, extrarange = MEDIUM_RANGE_SOUND_EXTRARANGE)
qdel(src)
@@ -156,6 +156,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons)
icon_state = "extraction_point"
anchored = TRUE
density = FALSE
+ obj_flags = CAN_BE_HIT | UNIQUE_RENAME
var/beacon_network = "station"
/obj/structure/extraction_point/Initialize(mapload)
@@ -168,6 +169,15 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons)
GLOB.total_extraction_beacons -= src
return ..()
+/obj/structure/extraction_point/attack_hand(mob/living/user, list/modifiers)
+ . = ..()
+ balloon_alert_to_viewers("undeploying...")
+ if(!do_after(user, 1.5 SECONDS, src))
+ return
+ new /obj/item/fulton_core(drop_location())
+ playsound(src, 'sound/items/deconstruct.ogg', vol = 50, vary = TRUE, extrarange = MEDIUM_RANGE_SOUND_EXTRARANGE)
+ qdel(src)
+
/obj/structure/extraction_point/update_overlays()
. = ..()
. += emissive_appearance(icon, "[icon_state]_light", src, alpha = src.alpha)
diff --git a/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid_ai.dm b/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid_ai.dm
index e2c67af2467..c88178135dc 100644
--- a/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid_ai.dm
+++ b/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid_ai.dm
@@ -2,6 +2,7 @@
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
BB_BASIC_MOB_FLEEING = TRUE,
+ BB_BASIC_MOB_FLEE_DISTANCE = 5,
)
ai_movement = /datum/ai_movement/basic_avoidance
@@ -47,7 +48,6 @@
/datum/ai_behavior/run_away_from_target/mega_arachnid
clear_failed_targets = FALSE
- run_distance = 5
///only engage in melee combat against cuffed targets, otherwise keep throwing restraints at them
/datum/ai_planning_subtree/basic_melee_attack_subtree/mega_arachnid
diff --git a/code/modules/mob/living/basic/lavaland/basilisk/basilisk.dm b/code/modules/mob/living/basic/lavaland/basilisk/basilisk.dm
index c662870393c..45bfd74d23b 100644
--- a/code/modules/mob/living/basic/lavaland/basilisk/basilisk.dm
+++ b/code/modules/mob/living/basic/lavaland/basilisk/basilisk.dm
@@ -75,6 +75,7 @@
/datum/ai_controller/basic_controller/basilisk
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
+ BB_AGGRO_RANGE = 5,
)
ai_movement = /datum/ai_movement/basic_avoidance
diff --git a/code/modules/mob/living/basic/lavaland/goliath/goliath.dm b/code/modules/mob/living/basic/lavaland/goliath/goliath.dm
index 95df44a8326..b99e254853e 100644
--- a/code/modules/mob/living/basic/lavaland/goliath/goliath.dm
+++ b/code/modules/mob/living/basic/lavaland/goliath/goliath.dm
@@ -44,6 +44,8 @@
COOLDOWN_DECLARE(ability_animation_cooldown)
/// Our base tentacles ability
var/datum/action/cooldown/mob_cooldown/goliath_tentacles/tentacles
+ /// Our long-ranged tentacles ability
+ var/datum/action/cooldown/mob_cooldown/tentacle_grasp/tentacle_line
/// Things we want to eat off the floor (or a plate, we're not picky)
var/static/list/goliath_foods = list(/obj/item/food/grown/ash_flora, /obj/item/food/bait/worm)
@@ -70,9 +72,9 @@
var/datum/action/cooldown/mob_cooldown/tentacle_burst/melee_tentacles = new (src)
melee_tentacles.Grant(src)
AddComponent(/datum/component/revenge_ability, melee_tentacles, targetting = ai_controller.blackboard[BB_TARGETTING_DATUM], max_range = 1, target_self = TRUE)
- var/datum/action/cooldown/mob_cooldown/tentacle_grasp/ranged_tentacles = new (src)
- ranged_tentacles.Grant(src)
- AddComponent(/datum/component/revenge_ability, ranged_tentacles, targetting = ai_controller.blackboard[BB_TARGETTING_DATUM], min_range = 2, max_range = 9)
+ tentacle_line = new (src)
+ tentacle_line.Grant(src)
+ AddComponent(/datum/component/revenge_ability, tentacle_line, targetting = ai_controller.blackboard[BB_TARGETTING_DATUM], min_range = 2, max_range = 9)
tentacles_ready()
RegisterSignal(src, COMSIG_MOB_ABILITY_FINISHED, PROC_REF(used_ability))
@@ -82,6 +84,7 @@
/mob/living/basic/mining/goliath/Destroy()
QDEL_NULL(tentacles)
+ QDEL_NULL(tentacle_line)
return ..()
/mob/living/basic/mining/goliath/examine(mob/user)
@@ -167,6 +170,12 @@
. = ..()
faction = new_friend.faction.Copy()
+/mob/living/basic/mining/goliath/RangedAttack(atom/atom_target, modifiers)
+ tentacles?.Trigger(target = atom_target)
+
+/mob/living/basic/mining/goliath/ranged_secondary_attack(atom/atom_target, modifiers)
+ tentacle_line?.Trigger(target = atom_target)
+
/// Legacy Goliath mob with different sprites, largely the same behaviour
/mob/living/basic/mining/goliath/ancient
name = "ancient goliath"
diff --git a/code/modules/mob/living/basic/lavaland/hivelord/hivelord.dm b/code/modules/mob/living/basic/lavaland/hivelord/hivelord.dm
new file mode 100644
index 00000000000..256ab1fbd8f
--- /dev/null
+++ b/code/modules/mob/living/basic/lavaland/hivelord/hivelord.dm
@@ -0,0 +1,114 @@
+/// Mob which retreats and spawns annoying sub-mobs to attack you
+/mob/living/basic/mining/hivelord
+ name = "hivelord"
+ desc = "A levitating swarm of tiny creatures which act as a single individual. When threatened or hunting they rapidly replicate additional short-lived bodies."
+ icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
+ icon_state = "hivelord"
+ icon_living = "hivelord"
+ // icon_aggro = "hivelord_alert"
+ icon_dead = "hivelord_dead"
+ icon_gib = "syndicate_gib"
+ mob_biotypes = MOB_ORGANIC
+ speed = 2
+ maxHealth = 75
+ health = 75
+ melee_damage_lower = 0
+ melee_damage_upper = 0
+ attack_verb_continuous = "weakly tackles"
+ attack_verb_simple = "weakly tackles"
+ speak_emote = list("telepathically cries")
+ attack_sound = 'sound/weapons/pierce.ogg'
+ throw_blocked_message = "passes between the bodies of the"
+ obj_damage = 0
+ pass_flags = PASSTABLE
+ ai_controller = /datum/ai_controller/basic_controller/hivelord
+ /// Mobs to spawn when we die, varedit this to be recursive to give the players a fun surprise
+ var/death_spawn_type = /mob/living/basic/hivelord_brood
+ /// Action which spawns worms
+ var/datum/action/cooldown/mob_cooldown/hivelord_spawn/spawn_brood
+
+/mob/living/basic/mining/hivelord/Initialize(mapload)
+ . = ..()
+ var/static/list/death_loot = list(/obj/item/organ/internal/monster_core/regenerative_core)
+ AddElement(/datum/element/relay_attackers)
+ AddElement(/datum/element/death_drops, death_loot)
+ AddComponent(/datum/component/clickbox, icon_state = "hivelord", max_scale = INFINITY, dead_state = "hivelord_dead") // They writhe so much.
+ AddComponent(/datum/component/appearance_on_aggro, aggro_state = "hivelord_alert")
+ spawn_brood = new(src)
+ spawn_brood.Grant(src)
+ ai_controller.set_blackboard_key(BB_TARGETTED_ACTION, spawn_brood)
+
+/mob/living/basic/mining/hivelord/Destroy()
+ QDEL_NULL(spawn_brood)
+ return ..()
+
+/mob/living/basic/mining/hivelord/death(gibbed)
+ . = ..()
+ var/list/safe_turfs = RANGE_TURFS(1, src) - get_turf(src)
+ for (var/turf/check_turf as anything in safe_turfs)
+ if (check_turf.is_blocked_turf(exclude_mobs = TRUE))
+ safe_turfs -= check_turf
+
+ var/turf/our_turf = get_turf(src)
+ for (var/i in 1 to 3)
+ if (!length(safe_turfs))
+ return
+ var/turf/land_turf = pick_n_take(safe_turfs)
+ var/obj/effect/temp_visual/hivebrood_spawn/forecast = new(land_turf)
+ forecast.create_from(death_spawn_type, our_turf, CALLBACK(src, PROC_REF(complete_spawn), land_turf))
+
+/// Spawns a worm on the specified turf
+/mob/living/basic/mining/hivelord/proc/complete_spawn(turf/spawn_turf)
+ var/mob/living/brood = new death_spawn_type(spawn_turf)
+ brood.faction = faction
+ brood.ai_controller?.set_blackboard_key(ai_controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET])
+ brood.dir = get_dir(src, spawn_turf)
+
+/mob/living/basic/mining/hivelord/RangedAttack(atom/atom_target, modifiers)
+ spawn_brood?.Trigger(target = atom_target)
+
+/// Attack worms spawned by the hivelord
+/mob/living/basic/hivelord_brood
+ name = "hivelord brood"
+ desc = "Short-lived attack form of the hivelord. One isn't much of a threat, but..."
+ icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
+ icon_state = "hivelord_brood"
+ icon_living = "hivelord_brood"
+ icon_dead = "hivelord_brood"
+ icon_gib = "syndicate_gib"
+ friendly_verb_continuous = "chirrups near"
+ friendly_verb_simple = "chirrup near"
+ mob_size = MOB_SIZE_SMALL
+ basic_mob_flags = DEL_ON_DEATH
+ pass_flags = PASSTABLE | PASSMOB
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
+ faction = list(FACTION_MINING)
+ unsuitable_atmos_damage = 0
+ minimum_survivable_temperature = 0
+ maximum_survivable_temperature = INFINITY
+ speed = 1.5
+ maxHealth = 1
+ health = 1
+ melee_damage_lower = 2
+ melee_damage_upper = 2
+ attack_verb_continuous = "bites"
+ attack_verb_simple = "bite"
+ speak_emote = list("telepathically cries")
+ attack_sound = 'sound/weapons/bite.ogg'
+ attack_vis_effect = ATTACK_EFFECT_BITE
+ obj_damage = 0
+ density = FALSE
+ ai_controller = /datum/ai_controller/basic_controller/simple_hostile
+
+/mob/living/basic/hivelord_brood/Initialize(mapload)
+ . = ..()
+ add_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE), INNATE_TRAIT)
+ AddElement(/datum/element/simple_flying)
+ AddComponent(/datum/component/swarming)
+ AddComponent(/datum/component/clickbox, icon_state = "hivelord", max_scale = INFINITY)
+ addtimer(CALLBACK(src, PROC_REF(death)), 10 SECONDS)
+
+/mob/living/basic/hivelord_brood/death(gibbed)
+ if (!gibbed)
+ new /obj/effect/temp_visual/hive_spawn_wither(get_turf(src), /* copy_from = */ src)
+ return ..()
diff --git a/code/modules/mob/living/basic/lavaland/hivelord/hivelord_ai.dm b/code/modules/mob/living/basic/lavaland/hivelord/hivelord_ai.dm
new file mode 100644
index 00000000000..fd7983de397
--- /dev/null
+++ b/code/modules/mob/living/basic/lavaland/hivelord/hivelord_ai.dm
@@ -0,0 +1,14 @@
+/// Basically just keep away and shit out worms
+/datum/ai_controller/basic_controller/hivelord
+ blackboard = list(
+ BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
+ BB_AGGRO_RANGE = 5, // Only get mad at people nearby
+ )
+
+ ai_movement = /datum/ai_movement/basic_avoidance
+ idle_behavior = /datum/idle_behavior/idle_random_walk
+ planning_subtrees = list(
+ /datum/ai_planning_subtree/simple_find_target,
+ /datum/ai_planning_subtree/maintain_distance,
+ /datum/ai_planning_subtree/targeted_mob_ability,
+ )
diff --git a/code/modules/mob/living/basic/lavaland/hivelord/spawn_hivelord_brood.dm b/code/modules/mob/living/basic/lavaland/hivelord/spawn_hivelord_brood.dm
new file mode 100644
index 00000000000..3fee2a003f3
--- /dev/null
+++ b/code/modules/mob/living/basic/lavaland/hivelord/spawn_hivelord_brood.dm
@@ -0,0 +1,124 @@
+/// Spawns a little worm nearby
+/datum/action/cooldown/mob_cooldown/hivelord_spawn
+ name = "Spawn Brood"
+ desc = "Release an attack form to an adjacent square to attack your target or anyone nearby."
+ button_icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
+ button_icon_state = "hivelord_brood"
+ background_icon_state = "bg_demon"
+ overlay_icon_state = "bg_demon_border"
+ click_to_activate = TRUE
+ cooldown_time = 2 SECONDS
+ melee_cooldown_time = 0
+ check_flags = AB_CHECK_CONSCIOUS | AB_CHECK_INCAPACITATED
+ shared_cooldown = NONE
+ /// If a mob is not clicked directly, inherit targetting data from this blackboard key and setting it upon this target key
+ var/ai_target_key = BB_BASIC_MOB_CURRENT_TARGET
+ /// What are we actually spawning?
+ var/spawn_type = /mob/living/basic/hivelord_brood
+ /// Do we automatically fire with no cooldown when damaged?
+ var/trigger_on_hit = TRUE
+ /// Minimum time between triggering on hit
+ var/on_hit_delay = 1 SECONDS
+ /// Delay between triggering on hit
+ COOLDOWN_DECLARE(on_hit_cooldown)
+
+/datum/action/cooldown/mob_cooldown/hivelord_spawn/Grant(mob/granted_to)
+ . = ..()
+ if (isnull(owner))
+ return
+ if (trigger_on_hit)
+ RegisterSignal(owner, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(on_attacked))
+
+/datum/action/cooldown/mob_cooldown/hivelord_spawn/Remove(mob/removed_from)
+ UnregisterSignal(removed_from, COMSIG_ATOM_WAS_ATTACKED)
+ return ..()
+
+/datum/action/cooldown/mob_cooldown/hivelord_spawn/Activate(atom/target)
+ . = ..()
+ if (!spawn_brood(target, target_turf = get_turf(target)))
+ StartCooldown(0.5 SECONDS)
+ return
+ StartCooldown()
+
+/// Called when someone whacks us
+/datum/action/cooldown/mob_cooldown/hivelord_spawn/proc/on_attacked(atom/victim, atom/attacker, attack_flags)
+ SIGNAL_HANDLER
+ if (!trigger_on_hit || !(attack_flags & ATTACKER_DAMAGING_ATTACK) || !COOLDOWN_FINISHED(src, on_hit_cooldown))
+ return
+ COOLDOWN_START(src, on_hit_cooldown, on_hit_delay)
+ spawn_brood(attacker, target_turf = get_step_away(owner, attacker), feedback = FALSE)
+
+/// Spawn a funny little worm
+/datum/action/cooldown/mob_cooldown/hivelord_spawn/proc/spawn_brood(target, turf/target_turf, feedback = TRUE)
+ var/ai_target = isliving(target) ? target : null
+ if (isnull(ai_target))
+ ai_target = owner.ai_controller?.blackboard[ai_target_key]
+
+ var/dir_to_target = get_dir(owner, target_turf)
+ var/list/target_turfs = list()
+ for(var/i in -1 to 1)
+ var/turn_amount = rand(-1, 1) * 45
+ var/test_dir = turn(dir_to_target, turn_amount)
+ var/turf/test_turf = get_step(owner, test_dir)
+ if (test_turf.is_blocked_turf(exclude_mobs = TRUE))
+ continue
+ target_turfs += test_turf
+
+ if (!length(target_turfs))
+ if (feedback)
+ owner.balloon_alert(owner, "no room!")
+ StartCooldown(0.5 SECONDS)
+ return FALSE
+
+ var/turf/land_turf = pick(target_turfs)
+ var/obj/effect/temp_visual/hivebrood_spawn/forecast = new(land_turf)
+ forecast.create_from(spawn_type, get_turf(owner), CALLBACK(src, PROC_REF(complete_spawn), land_turf, ai_target))
+ StartCooldown()
+
+ return TRUE
+
+/// Actually create a mob
+/datum/action/cooldown/mob_cooldown/hivelord_spawn/proc/complete_spawn(turf/spawn_turf, target)
+ var/mob/living/brood = new spawn_type(spawn_turf)
+ brood.faction = owner.faction
+ brood.ai_controller?.set_blackboard_key(ai_target_key, target)
+ brood.dir = get_dir(owner, spawn_turf)
+
+#define BROOD_ARC_Y_OFFSET 8
+#define BROOD_ARC_ROTATION 45
+
+/// Fast animation to show a worm spawning
+/obj/effect/temp_visual/hivebrood_spawn
+ name = "brood spawn"
+ duration = 0.3 SECONDS
+ alpha = 0
+
+/// Set up our visuals and start a timer for a callback
+/obj/effect/temp_visual/hivebrood_spawn/proc/create_from(mob/living/spawn_type, turf/spawn_from, datum/callback/on_completed)
+ addtimer(on_completed, duration, TIMER_DELETE_ME)
+
+ var/turf/my_turf = get_turf(src)
+ dir = get_dir(spawn_from, my_turf)
+ var/move_x = (my_turf.x - spawn_from.x) * world.icon_size
+ var/move_y = (my_turf.y - spawn_from.y) * world.icon_size
+ pixel_x = -move_x
+ pixel_y = -move_y
+
+ icon = initial(spawn_type.icon)
+ icon_state = initial(spawn_type.icon_state)
+
+
+ animate(src, pixel_x = 0, time = duration)
+ animate(src, pixel_y = BROOD_ARC_Y_OFFSET - (move_y * 0.5), time = duration * 0.5, flags = ANIMATION_PARALLEL, easing = SINE_EASING | EASE_OUT)
+ animate(pixel_y = 0, time = duration * 0.5, easing = SINE_EASING | EASE_IN)
+ animate(src, alpha = 255, time = duration * 0.5, flags = ANIMATION_PARALLEL)
+
+ if (dir & (NORTH | EAST))
+ transform = matrix().Turn(-BROOD_ARC_ROTATION)
+ animate(src, transform = matrix(), time = duration, flags = ANIMATION_PARALLEL)
+ else
+ transform = matrix().Turn(BROOD_ARC_ROTATION)
+ animate(src, transform = matrix(), time = duration, flags = ANIMATION_PARALLEL)
+
+#undef BROOD_ARC_Y_OFFSET
+#undef BROOD_ARC_ROTATION
diff --git a/code/modules/mob/living/basic/lavaland/legion/legion.dm b/code/modules/mob/living/basic/lavaland/legion/legion.dm
new file mode 100644
index 00000000000..7c6bd0fd170
--- /dev/null
+++ b/code/modules/mob/living/basic/lavaland/legion/legion.dm
@@ -0,0 +1,158 @@
+/**
+ * Avoids players while throwing skulls at them.
+ * Legion skulls heal allies, bite enemies, and infest dying humans to make more legions.
+ */
+/mob/living/basic/mining/legion
+ name = "legion"
+ desc = "You can still see what was once a human under the shifting mass of corruption."
+ icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
+ icon_state = "legion"
+ icon_living = "legion"
+ icon_dead = "legion"
+ icon_gib = "syndicate_gib"
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
+ basic_mob_flags = DEL_ON_DEATH
+ speed = 3
+ maxHealth = 75
+ health = 75
+ obj_damage = 60
+ melee_damage_lower = 15
+ melee_damage_upper = 15
+ attack_verb_continuous = "lashes out at"
+ attack_verb_simple = "lash out at"
+ speak_emote = list("gurgles")
+ attack_sound = 'sound/weapons/pierce.ogg'
+ throw_blocked_message = "bounces harmlessly off of"
+ crusher_loot = /obj/item/crusher_trophy/legion_skull
+ death_message = "wails in chorus and dissolves into quivering flesh."
+ ai_controller = /datum/ai_controller/basic_controller/legion
+ /// What kind of mob do we spawn?
+ var/brood_type = /mob/living/basic/legion_brood
+ /// What kind of corpse spawner do we leave behind on death?
+ var/corpse_type = /obj/effect/mob_spawn/corpse/human/legioninfested
+ /// Who is inside of us?
+ var/mob/living/stored_mob
+
+/mob/living/basic/mining/legion/Initialize(mapload)
+ . = ..()
+ AddElement(/datum/element/death_drops, get_loot_list())
+ AddElement(/datum/element/content_barfer)
+
+ var/datum/action/cooldown/mob_cooldown/skull_launcher/skull_launcher = new(src)
+ skull_launcher.Grant(src)
+ skull_launcher.spawn_type = brood_type
+ ai_controller.blackboard[BB_TARGETTED_ACTION] = skull_launcher
+
+/// Create what we want to drop on death, in proc form so we can always return a static list
+/mob/living/basic/mining/legion/proc/get_loot_list()
+ var/static/list/death_loot = list(/obj/item/organ/internal/monster_core/regenerative_core/legion)
+ return death_loot
+
+/mob/living/basic/mining/legion/Exited(atom/movable/gone, direction)
+ . = ..()
+ if (gone != stored_mob)
+ return
+ ai_controller.clear_blackboard_key(BB_LEGION_CORPSE)
+ stored_mob.remove_status_effect(/datum/status_effect/grouped/stasis, STASIS_LEGION_EATEN)
+ stored_mob.add_mood_event(MOOD_CATEGORY_LEGION_CORE, /datum/mood_event/healsbadman/long_term) // This will still probably mostly be gone before you are alive
+ stored_mob = null
+
+/mob/living/basic/mining/legion/death(gibbed)
+ if (isnull(stored_mob))
+ new corpse_type(loc)
+ return ..()
+
+/// Put a corpse in this guy
+/mob/living/basic/mining/legion/proc/consume(mob/living/consumed)
+ new /obj/effect/gibspawner/generic(consumed.loc)
+ gender = consumed.gender
+ name = consumed.real_name
+ consumed.investigate_log("has been killed by hivelord infestation.", INVESTIGATE_DEATHS)
+ consumed.death()
+ consumed.extinguish_mob()
+ consumed.fully_heal(HEAL_DAMAGE)
+ consumed.apply_status_effect(/datum/status_effect/grouped/stasis, STASIS_LEGION_EATEN)
+ consumed.forceMove(src)
+ ai_controller?.set_blackboard_key(BB_LEGION_CORPSE, consumed)
+ ai_controller?.set_blackboard_key(BB_LEGION_RECENT_LINES, consumed.copy_recent_speech(line_chance = 80))
+ stored_mob = consumed
+ visible_message(span_warning("[src] staggers to [p_their()] feet!"))
+ if (prob(75))
+ return
+ // Congratulations you have won a special prize: cancer
+ var/obj/item/organ/internal/legion_tumour/cancer = new()
+ cancer.Insert(consumed, special = TRUE, drop_if_replaced = FALSE)
+
+/// A Legion which only drops skeletons instead of corpses which might have fun loot, so it cannot be farmed
+/mob/living/basic/mining/legion/spawner_made
+ corpse_type = /obj/effect/mob_spawn/corpse/human/legioninfested/skeleton/charred
+
+
+/// Like a Legion but it's an adorable snowman
+/mob/living/basic/mining/legion/snow
+ name = "snow legion"
+ desc = "You can vaguely see what was once a human under the densely packed snow. Cute, but macabre."
+ icon = 'icons/mob/simple/icemoon/icemoon_monsters.dmi'
+ icon_state = "snowlegion"
+ icon_living = "snowlegion"
+ // icon_aggro = "snowlegion_alive"
+ icon_dead = "snowlegion"
+ brood_type = /mob/living/basic/legion_brood/snow
+ corpse_type = /obj/effect/mob_spawn/corpse/human/legioninfested/snow
+
+/mob/living/basic/mining/legion/snow/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/appearance_on_aggro, aggro_state = "snowlegion_alive") // Surprise! I was real!
+
+/// As Snow Legion but spawns corpses which don't have any exciting loot
+/mob/living/basic/mining/legion/snow/spawner_made
+ corpse_type = /obj/effect/mob_spawn/corpse/human/legioninfested/skeleton
+
+
+/// Like a Legion but shorter and faster
+/mob/living/basic/mining/legion/dwarf
+ name = "dwarf legion"
+ desc = "You can still see what was once a rather small human under the shifting mass of corruption."
+ icon_state = "dwarf_legion"
+ icon_living = "dwarf_legion"
+ icon_dead = "dwarf_legion"
+ maxHealth = 60
+ health = 60
+ speed = 2
+ crusher_drop_chance = 20
+ corpse_type = /obj/effect/mob_spawn/corpse/human/legioninfested/dwarf
+
+
+/// Like a Legion but larger and spawns regular Legions, not currently used anywhere and very soulful
+/mob/living/basic/mining/legion/large
+ name = "myriad"
+ desc = "A legion of legions, a dead end to whatever form the Necropolis was attempting to create."
+ icon = 'icons/mob/simple/lavaland/64x64megafauna.dmi'
+ icon_state = "legion"
+ icon_living = "legion"
+ icon_dead = "legion"
+ health_doll_icon = "legion"
+ speed = 5
+ health = 450
+ maxHealth = 450
+ melee_damage_lower = 20
+ melee_damage_upper = 20
+ obj_damage = 30
+ pixel_x = -16
+ sentience_type = SENTIENCE_BOSS
+
+/mob/living/basic/mining/legion/large/Initialize(mapload)
+ . = ..()
+ AddComponent(\
+ /datum/component/spawner,\
+ spawn_types = list(/mob/living/basic/mining/legion),\
+ spawn_time = 20 SECONDS,\
+ max_spawned = 3,\
+ spawn_text = "peels itself off from",\
+ faction = faction,\
+ )
+
+/// Create what we want to drop on death, in proc form so we can always return a static list
+/mob/living/basic/mining/legion/large/get_loot_list()
+ var/static/list/death_loot = list(/obj/item/organ/internal/monster_core/regenerative_core/legion = 3, /obj/effect/mob_spawn/corpse/human/legioninfested = 4)
+ return death_loot
diff --git a/code/modules/mob/living/basic/lavaland/legion/legion_ai.dm b/code/modules/mob/living/basic/lavaland/legion/legion_ai.dm
new file mode 100644
index 00000000000..6b3525cb32a
--- /dev/null
+++ b/code/modules/mob/living/basic/lavaland/legion/legion_ai.dm
@@ -0,0 +1,77 @@
+/// Keep away and launch skulls at every opportunity, prioritising injured allies
+/datum/ai_controller/basic_controller/legion
+ blackboard = list(
+ BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/attack_until_dead/legion,
+ BB_BASIC_MOB_FLEEING = TRUE,
+ BB_AGGRO_RANGE = 5, // Unobservant
+ BB_BASIC_MOB_FLEE_DISTANCE = 6,
+ )
+
+ ai_movement = /datum/ai_movement/basic_avoidance
+ idle_behavior = /datum/idle_behavior/idle_random_walk
+ planning_subtrees = list(
+ /datum/ai_planning_subtree/random_speech/legion,
+ /datum/ai_planning_subtree/simple_find_target,
+ /datum/ai_planning_subtree/targeted_mob_ability,
+ /datum/ai_planning_subtree/flee_target/legion,
+ )
+
+/// Chase and attack whatever we are targetting, if it's friendly we will heal them
+/datum/ai_controller/basic_controller/legion_brood
+ blackboard = list(
+ BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/attack_until_dead/legion,
+ )
+
+ ai_movement = /datum/ai_movement/basic_avoidance
+ idle_behavior = /datum/idle_behavior/idle_random_walk
+ planning_subtrees = list(
+ /datum/ai_planning_subtree/simple_find_target,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
+ )
+
+/// Target nearby friendlies if they are hurt (and are not themselves Legions)
+/datum/targetting_datum/basic/attack_until_dead/legion
+
+/datum/targetting_datum/basic/attack_until_dead/legion/faction_check(mob/living/living_mob, mob/living/the_target)
+ if (!living_mob.faction_check_mob(the_target, exact_match = check_factions_exactly))
+ return FALSE
+ if (istype(the_target, living_mob.type))
+ return TRUE
+ var/atom/created_by = living_mob.ai_controller.blackboard[BB_LEGION_BROOD_CREATOR]
+ if (!QDELETED(created_by) && istype(the_target, created_by.type))
+ return TRUE
+ return the_target.stat == DEAD || the_target.health >= the_target.maxHealth
+
+/// Don't run away from friendlies
+/datum/ai_planning_subtree/flee_target/legion
+
+/datum/ai_planning_subtree/flee_target/legion/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
+ var/mob/living/target = controller.blackboard[target_key]
+ if (QDELETED(target) || target.faction_check_mob(controller.pawn))
+ return // Only flee if we have a hostile target
+ return ..()
+
+/// Make spooky sounds, if we have a corpse inside then impersonate them
+/datum/ai_planning_subtree/random_speech/legion
+ speech_chance = 1
+ speak = list("Come...", "Legion...", "Why...?")
+ emote_hear = list("groans.", "wails.", "whimpers.")
+ emote_see = list("twitches.", "shudders.")
+ /// Stuff to specifically say into a radio
+ var/list/radio_speech = list("Come...", "Why...?")
+
+/datum/ai_planning_subtree/random_speech/legion/speak(datum/ai_controller/controller)
+ var/mob/living/carbon/human/victim = controller.blackboard[BB_LEGION_CORPSE]
+ if (QDELETED(victim) || prob(30))
+ return ..()
+
+ var/list/remembered_speech = controller.blackboard[BB_LEGION_RECENT_LINES] || list()
+
+ if (length(remembered_speech) && prob(50)) // Don't spam the radio
+ controller.queue_behavior(/datum/ai_behavior/perform_speech, pick(remembered_speech))
+ return
+
+ var/obj/item/radio/mob_radio = locate() in victim.contents
+ if (QDELETED(mob_radio))
+ return ..() // No radio, just talk funny
+ controller.queue_behavior(/datum/ai_behavior/perform_speech_radio, pick(radio_speech + remembered_speech), mob_radio, list(RADIO_CHANNEL_SUPPLY, RADIO_CHANNEL_COMMON))
diff --git a/code/modules/mob/living/basic/lavaland/legion/legion_brood.dm b/code/modules/mob/living/basic/lavaland/legion/legion_brood.dm
new file mode 100644
index 00000000000..bc21bd0e506
--- /dev/null
+++ b/code/modules/mob/living/basic/lavaland/legion/legion_brood.dm
@@ -0,0 +1,99 @@
+/// A spooky skull which heals lavaland mobs, attacks miners, and infests their bodies
+/mob/living/basic/legion_brood
+ name = "legion"
+ desc = "One of many."
+ icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
+ icon_state = "legion_head"
+ icon_living = "legion_head"
+ icon_dead = "legion_head"
+ icon_gib = "syndicate_gib"
+ basic_mob_flags = DEL_ON_DEATH
+ mob_size = MOB_SIZE_SMALL
+ pass_flags = PASSTABLE | PASSMOB
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
+ faction = list(FACTION_MINING)
+ unsuitable_atmos_damage = 0
+ minimum_survivable_temperature = 0
+ maximum_survivable_temperature = INFINITY
+ friendly_verb_continuous = "chatters near"
+ friendly_verb_simple = "chatter near"
+ maxHealth = 1
+ health = 1
+ melee_damage_lower = 12
+ melee_damage_upper = 12
+ obj_damage = 0
+ attack_verb_continuous = "bites"
+ attack_verb_simple = "bite"
+ attack_vis_effect = ATTACK_EFFECT_BITE
+ speak_emote = list("echoes") // who the fuck speaking as this mob it dies 10 seconds after it spawns
+ attack_sound = 'sound/weapons/pierce.ogg'
+ density = FALSE
+ ai_controller = /datum/ai_controller/basic_controller/legion_brood
+ /// Reference to a guy who made us
+ var/mob/living/created_by
+
+/mob/living/basic/legion_brood/Initialize(mapload)
+ . = ..()
+ add_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE), INNATE_TRAIT)
+ AddElement(/datum/element/simple_flying)
+ AddComponent(/datum/component/swarming)
+ AddComponent(/datum/component/clickbox, icon_state = "sphere", max_scale = 2)
+ addtimer(CALLBACK(src, PROC_REF(death)), 10 SECONDS)
+
+/mob/living/basic/legion_brood/death(gibbed)
+ if (!gibbed)
+ new /obj/effect/temp_visual/hive_spawn_wither(get_turf(src), /* copy_from = */ src)
+ return ..()
+
+/mob/living/basic/legion_brood/melee_attack(mob/living/target, list/modifiers, ignore_cooldown)
+ if (ishuman(target) && target.stat > SOFT_CRIT)
+ infest(target)
+ return
+ if (isliving(target) && faction_check_mob(target) && !istype(target, created_by?.type))
+ visible_message(span_warning("[src] melds with [target]'s flesh!"))
+ target.apply_status_effect(/datum/status_effect/regenerative_core)
+ new /obj/effect/temp_visual/heal(get_turf(target), COLOR_HEALING_CYAN)
+ death()
+ return
+ return ..()
+
+/// Turn the targetted mob into one of us
+/mob/living/basic/legion_brood/proc/infest(mob/living/target)
+ visible_message(span_warning("[name] burrows into the flesh of [target]!"))
+ var/spawn_type = get_legion_type(target)
+ var/mob/living/basic/mining/legion/new_legion = new spawn_type(loc)
+ new_legion.consume(target)
+ new_legion.faction = faction.Copy()
+ qdel(src)
+
+/// Returns the kind of legion we make out of the target
+/mob/living/basic/legion_brood/proc/get_legion_type(mob/living/target)
+ if (HAS_TRAIT(target, TRAIT_DWARF))
+ return /mob/living/basic/mining/legion/dwarf
+ return /mob/living/basic/mining/legion
+
+/// Sets someone as our creator, mostly so you can't use skulls to heal yourself
+/mob/living/basic/legion_brood/proc/assign_creator(mob/living/creator, copy_full_faction = TRUE)
+ if (copy_full_faction)
+ faction = creator.faction.Copy()
+ else
+ faction |= REF(creator)
+ created_by = creator
+ ai_controller?.set_blackboard_key(BB_LEGION_BROOD_CREATOR, creator)
+ RegisterSignal(creator, COMSIG_QDELETING, PROC_REF(creator_destroyed))
+
+/// Reference handling
+/mob/living/basic/legion_brood/proc/creator_destroyed()
+ SIGNAL_HANDLER
+ created_by = null
+
+/// Like the Legion's summoned skull but funnier (it's snow now)
+/mob/living/basic/legion_brood/snow
+ name = "snow legion"
+ icon = 'icons/mob/simple/icemoon/icemoon_monsters.dmi'
+ icon_state = "snowlegion_head"
+ icon_living = "snowlegion_head"
+ icon_dead = "snowlegion_head"
+
+/mob/living/basic/legion_brood/snow/get_legion_type(mob/living/target)
+ return /mob/living/basic/mining/legion/snow
diff --git a/code/modules/mob/living/basic/lavaland/legion/legion_tumour.dm b/code/modules/mob/living/basic/lavaland/legion/legion_tumour.dm
new file mode 100644
index 00000000000..078af57de2a
--- /dev/null
+++ b/code/modules/mob/living/basic/lavaland/legion/legion_tumour.dm
@@ -0,0 +1,159 @@
+/// Left behind when a legion infects you, for medical enrichment
+/obj/item/organ/internal/legion_tumour
+ name = "legion tumour"
+ desc = "A mass of pulsing flesh and dark tendrils, containing the power to regenerate flesh at a terrible cost."
+ failing_desc = "pulses and writhes with horrible life, reaching towards you with its tendrils!"
+ icon = 'icons/obj/medical/organs/mining_organs.dmi'
+ icon_state = "legion_remains"
+ zone = BODY_ZONE_CHEST
+ slot = ORGAN_SLOT_PARASITE_EGG
+ decay_factor = STANDARD_ORGAN_DECAY * 3 // About 5 minutes outside of a host
+ /// What stage of growth the corruption has reached.
+ var/stage = 0
+ /// We apply this status effect periodically or when used on someone
+ var/applied_status = /datum/status_effect/regenerative_core
+ /// How long have we been in this stage?
+ var/elapsed_time = 0 SECONDS
+ /// How long does it take to advance one stage?
+ var/growth_time = 80 SECONDS // Long enough that if you go back to lavaland without realising it you're not totally fucked
+ /// What kind of mob will we transform into?
+ var/spawn_type = /mob/living/basic/mining/legion
+ /// Spooky sounds to play as you start to turn
+ var/static/list/spooky_sounds = list(
+ 'sound/voice/lowHiss1.ogg',
+ 'sound/voice/lowHiss2.ogg',
+ 'sound/voice/lowHiss3.ogg',
+ 'sound/voice/lowHiss4.ogg',
+ )
+
+/obj/item/organ/internal/legion_tumour/Initialize(mapload)
+ . = ..()
+ animate_pulse()
+
+/obj/item/organ/internal/legion_tumour/apply_organ_damage(damage_amount, maximum, required_organ_flag)
+ var/was_failing = organ_flags & ORGAN_FAILING
+ . = ..()
+ if (was_failing != (organ_flags & ORGAN_FAILING))
+ animate_pulse()
+
+/obj/item/organ/internal/legion_tumour/set_organ_damage(damage_amount, required_organ_flag)
+ . = ..()
+ animate_pulse()
+
+/// Do a heartbeat animation depending on if we're failing or not
+/obj/item/organ/internal/legion_tumour/proc/animate_pulse()
+ animate(src, transform = matrix()) // Stop any current animation
+
+ var/speed_divider = organ_flags & ORGAN_FAILING ? 2 : 1
+
+ animate(src, transform = matrix().Scale(1.1), time = 0.5 SECONDS / speed_divider, easing = SINE_EASING | EASE_OUT, loop = -1, flags = ANIMATION_PARALLEL)
+ animate(transform = matrix(), time = 0.5 SECONDS / speed_divider, easing = SINE_EASING | EASE_IN)
+ animate(transform = matrix(), time = 2 SECONDS / speed_divider)
+
+/obj/item/organ/internal/legion_tumour/Remove(mob/living/carbon/egg_owner, special)
+ . = ..()
+ stage = 0
+ elapsed_time = 0
+
+/obj/item/organ/internal/legion_tumour/attack(mob/living/target, mob/living/user, params)
+ if (try_apply(target, user))
+ qdel(src)
+ return
+ return ..()
+
+/// Smear it on someone like a regen core, why not. Make sure they're alive though.
+/obj/item/organ/internal/legion_tumour/proc/try_apply(mob/living/target, mob/user)
+ if(!user.Adjacent(target) || !isliving(target))
+ return FALSE
+
+ if (target.stat <= SOFT_CRIT && !(organ_flags & ORGAN_FAILING))
+ target.add_mood_event(MOOD_CATEGORY_LEGION_CORE, /datum/mood_event/healsbadman)
+ target.apply_status_effect(applied_status)
+
+ if (target != user)
+ target.visible_message(span_notice("[user] splatters [target] with [src]... Disgusting tendrils pull [target.p_their()] wounds shut!"))
+ else
+ to_chat(user, span_notice("You smear [src] on yourself. Disgusting tendrils pull your wounds closed."))
+ return TRUE
+
+ if (!ishuman(target))
+ return FALSE
+
+ target.visible_message(span_boldwarning("[user] splatters [target] with [src]... and it springs into horrible life!"))
+ var/mob/living/basic/legion_brood/skull = new(target.loc)
+ skull.melee_attack(target)
+ return TRUE
+
+/obj/item/organ/internal/legion_tumour/on_life(seconds_per_tick, times_fired)
+ . = ..()
+ if (QDELETED(src) || QDELETED(owner))
+ return
+
+ if (stage >= 2)
+ if(SPT_PROB(stage / 5, seconds_per_tick))
+ to_chat(owner, span_notice("You feel a bit better."))
+ owner.apply_status_effect(applied_status) // It's not all bad!
+ if(SPT_PROB(1, seconds_per_tick))
+ owner.emote("twitch")
+
+ switch(stage)
+ if(2, 3)
+ if(SPT_PROB(1, seconds_per_tick))
+ to_chat(owner, span_danger("Your chest spasms!"))
+ if(SPT_PROB(1, seconds_per_tick))
+ to_chat(owner, span_danger("You feel weak."))
+ if(SPT_PROB(1, seconds_per_tick))
+ SEND_SOUND(owner, sound(pick(spooky_sounds)))
+ if(SPT_PROB(2, seconds_per_tick))
+ owner.vomit()
+ if(4, 5)
+ if(SPT_PROB(2, seconds_per_tick))
+ to_chat(owner, span_danger("Something flexes under your skin."))
+ if(SPT_PROB(2, seconds_per_tick))
+ if (prob(40))
+ SEND_SOUND(owner, sound('sound/voice/ghost_whisper.ogg'))
+ else
+ SEND_SOUND(owner, sound(pick(spooky_sounds)))
+ if(SPT_PROB(3, seconds_per_tick))
+ owner.vomit(vomit_type = /obj/effect/decal/cleanable/vomit/old/black_bile)
+ if (prob(50))
+ var/turf/check_turf = get_step(owner.loc, owner.dir)
+ var/atom/land_turf = (check_turf.is_blocked_turf()) ? owner.loc : check_turf
+ var/mob/living/basic/legion_brood/child = new(land_turf)
+ child.assign_creator(owner, copy_full_faction = FALSE)
+
+ if(SPT_PROB(3, seconds_per_tick))
+ to_chat(owner, span_danger("Your muscles ache."))
+ owner.take_bodypart_damage(3)
+
+ if (stage == 5)
+ if (SPT_PROB(10, seconds_per_tick))
+ infest()
+ return
+
+ elapsed_time += seconds_per_tick SECONDS * ((organ_flags & ORGAN_FAILING) ? 3 : 1) // Let's call it "matured" rather than failed
+ if (elapsed_time < growth_time)
+ return
+ stage++
+ elapsed_time = 0
+ if (stage == 5)
+ to_chat(owner, span_bolddanger("Something is moving under your skin!"))
+
+/// Consume our host
+/obj/item/organ/internal/legion_tumour/proc/infest()
+ if (QDELETED(src) || QDELETED(owner))
+ return
+ owner.visible_message(span_boldwarning("Black tendrils burst from [owner]'s flesh, covering them in amorphous flesh!"))
+ var/mob/living/basic/mining/legion/new_legion = new spawn_type(owner.loc)
+ new_legion.consume(owner)
+ qdel(src)
+
+/obj/item/organ/internal/legion_tumour/on_find(mob/living/finder)
+ . = ..()
+ to_chat(finder, span_warning("There's an enormous tumour in [owner]'s [zone]!"))
+ if(stage < 4)
+ to_chat(finder, span_notice("Its tendrils seem to twitch towards the light."))
+ return
+ to_chat(finder, span_notice("Its pulsing tendrils reach all throughout the body."))
+ if(prob(stage * 2))
+ infest()
diff --git a/code/modules/mob/living/basic/lavaland/legion/spawn_legions.dm b/code/modules/mob/living/basic/lavaland/legion/spawn_legions.dm
new file mode 100644
index 00000000000..1ffcafecd56
--- /dev/null
+++ b/code/modules/mob/living/basic/lavaland/legion/spawn_legions.dm
@@ -0,0 +1,109 @@
+/// Spawns a little worm nearby
+/datum/action/cooldown/mob_cooldown/skull_launcher
+ name = "Launch Legion"
+ desc = "Propel a living piece of your body to a distant location."
+ button_icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
+ button_icon_state = "legion_head"
+ background_icon_state = "bg_demon"
+ overlay_icon_state = "bg_demon_border"
+ click_to_activate = TRUE
+ cooldown_time = 2 SECONDS
+ melee_cooldown_time = 0
+ check_flags = AB_CHECK_CONSCIOUS | AB_CHECK_INCAPACITATED
+ shared_cooldown = NONE
+ /// If a mob is not clicked directly, inherit targetting data from this blackboard key and setting it upon this target key
+ var/ai_target_key = BB_BASIC_MOB_CURRENT_TARGET
+ /// What are we actually spawning?
+ var/spawn_type = /mob/living/basic/legion_brood
+ /// How far can we fire?
+ var/max_range = 7
+
+/datum/action/cooldown/mob_cooldown/skull_launcher/Activate(atom/target)
+ var/turf/target_turf = get_turf(target)
+
+ if (get_dist(owner, target_turf) > max_range)
+ target_turf = get_ranged_target_turf_direct(owner, target_turf, max_range)
+
+ if (target_turf.is_blocked_turf())
+ var/list/near_turfs = RANGE_TURFS(1, target_turf) - target_turf
+ for (var/turf/check_turf as anything in near_turfs)
+ if (check_turf.is_blocked_turf())
+ near_turfs -= check_turf
+ if (length(near_turfs))
+ target_turf = pick(near_turfs)
+ else if(target_turf.is_blocked_turf(exclude_mobs = TRUE))
+ owner.balloon_alert(owner, "no room!")
+ StartCooldown(0.5 SECONDS)
+ return
+
+ var/ai_target = isliving(target) ? target : null
+ if (isnull(ai_target))
+ ai_target = owner.ai_controller?.blackboard[ai_target_key]
+
+ var/target_dir = get_dir(owner, target)
+
+ var/obj/effect/temp_visual/legion_skull_depart/launch = new(get_turf(owner))
+ launch.set_appearance(spawn_type)
+ launch.dir = target_dir
+ new /obj/effect/temp_visual/legion_brood_indicator(target_turf)
+ var/obj/effect/temp_visual/legion_skull_land/land = new(target_turf)
+ land.dir = target_dir
+ land.set_appearance(spawn_type, CALLBACK(src, PROC_REF(spawn_skull), target_turf, ai_target))
+ StartCooldown()
+
+/// Actually create a mob
+/datum/action/cooldown/mob_cooldown/skull_launcher/proc/spawn_skull(turf/spawn_location, target)
+ var/mob/living/basic/legion_brood/brood = new spawn_type(spawn_location)
+ if (istype(brood))
+ brood.assign_creator(owner)
+ brood.ai_controller?.set_blackboard_key(ai_target_key, target)
+ brood.dir = get_dir(owner, spawn_location)
+ if (!isnull(target))
+ brood.face_atom(target)
+ else
+ brood.dir = get_dir(owner, spawn_location)
+
+
+/// Animation for launching a skull
+/obj/effect/temp_visual/legion_skull_depart
+ name = "legion brood launch"
+ icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
+ icon_state = "legion_head"
+ duration = 0.25 SECONDS
+
+/// Copy appearance from the passed atom type
+/obj/effect/temp_visual/legion_skull_depart/proc/set_appearance(atom/spawned_type)
+ icon = initial(spawned_type.icon)
+ icon_state = initial(spawned_type.icon_state)
+ animate(src, alpha = 0, pixel_y = 72, time = duration)
+
+/// Animation for landing a skull
+/obj/effect/temp_visual/legion_skull_land
+ name = "legion brood land"
+ duration = 0.5 SECONDS
+ icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
+ icon_state = "legion_head"
+ alpha = 0
+ pixel_y = 72
+
+/// Copy appearance from the passed atom type and store what to do on animation complete
+/obj/effect/temp_visual/legion_skull_land/proc/set_appearance(atom/spawned_type, datum/callback/on_completed)
+ icon = initial(spawned_type.icon)
+ icon_state = initial(spawned_type.icon_state)
+ animate(src, alpha = 0, pixel_y = 72, time = duration / 2)
+ animate(alpha = 255, pixel_y = 0, time = duration / 2)
+ addtimer(on_completed, duration, TIMER_DELETE_ME)
+
+/// A skull is going to be here! Oh no!
+/obj/effect/temp_visual/legion_brood_indicator
+ name = "legion brood land"
+ duration = 0.75 SECONDS
+ layer = BELOW_MOB_LAYER
+ plane = GAME_PLANE
+ icon = 'icons/mob/telegraphing/telegraph.dmi'
+ icon_state = "skull"
+
+/obj/effect/temp_visual/legion_brood_indicator/Initialize(mapload)
+ . = ..()
+ animate(src, alpha = 255, time = 0.5 SECONDS)
+ animate(alpha = 0, time = 0.25 SECONDS)
diff --git a/code/modules/mob/living/basic/lavaland/mining.dm b/code/modules/mob/living/basic/lavaland/mining.dm
index 6b1d0de5739..0b6c4f321b6 100644
--- a/code/modules/mob/living/basic/lavaland/mining.dm
+++ b/code/modules/mob/living/basic/lavaland/mining.dm
@@ -2,12 +2,17 @@
/mob/living/basic/mining
icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
combat_mode = TRUE
+ status_flags = NONE //don't inherit standard basicmob flags
mob_size = MOB_SIZE_LARGE
mob_biotypes = MOB_ORGANIC|MOB_BEAST
faction = list(FACTION_MINING)
unsuitable_atmos_damage = 0
minimum_survivable_temperature = 0
maximum_survivable_temperature = INFINITY
+ // Pale purple, should be red enough to see stuff on lavaland
+ lighting_cutoff_red = 25
+ lighting_cutoff_green = 15
+ lighting_cutoff_blue = 35
/// Message to output if throwing damage is absorbed
var/throw_blocked_message = "bounces off"
/// What crusher trophy this mob drops, if any
diff --git a/code/modules/mob/living/basic/lavaland/watcher/watcher_ai.dm b/code/modules/mob/living/basic/lavaland/watcher/watcher_ai.dm
index 1f310ac229f..a25234817f3 100644
--- a/code/modules/mob/living/basic/lavaland/watcher/watcher_ai.dm
+++ b/code/modules/mob/living/basic/lavaland/watcher/watcher_ai.dm
@@ -9,9 +9,9 @@
planning_subtrees = list(
/datum/ai_planning_subtree/target_retaliate/check_faction,
/datum/ai_planning_subtree/simple_find_target,
+ /datum/ai_planning_subtree/maintain_distance,
/datum/ai_planning_subtree/use_mob_ability/gaze,
/datum/ai_planning_subtree/ranged_skirmish/watcher,
- /datum/ai_planning_subtree/maintain_distance,
)
/datum/ai_planning_subtree/use_mob_ability/gaze
diff --git a/code/modules/mob/living/basic/minebots/minebot_ai.dm b/code/modules/mob/living/basic/minebots/minebot_ai.dm
index 897cddb1401..a4b082f5dd1 100644
--- a/code/modules/mob/living/basic/minebots/minebot_ai.dm
+++ b/code/modules/mob/living/basic/minebots/minebot_ai.dm
@@ -60,6 +60,7 @@
/datum/ai_behavior/basic_ranged_attack/minebot
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT
+ avoid_friendly_fire = TRUE
/datum/ai_planning_subtree/basic_ranged_attack_subtree/minebot/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
var/mob/living/living_pawn = controller.pawn
diff --git a/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_behavior.dm b/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_behavior.dm
index 4cdaba09759..28cffa4ed8e 100644
--- a/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_behavior.dm
+++ b/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_behavior.dm
@@ -64,6 +64,8 @@
/datum/ai_behavior/basic_ranged_attack/hivebot
action_cooldown = 3 SECONDS
+ avoid_friendly_fire = TRUE
/datum/ai_behavior/basic_ranged_attack/hivebot_rapid
action_cooldown = 1.5 SECONDS
+ avoid_friendly_fire = TRUE
diff --git a/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_subtree.dm b/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_subtree.dm
index 347219d0ef0..5bd957a7609 100644
--- a/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_subtree.dm
+++ b/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_subtree.dm
@@ -32,7 +32,7 @@
/datum/ai_controller/basic_controller/hivebot/ranged/rapid
planning_subtrees = list(
/datum/ai_planning_subtree/simple_find_target,
- /datum/ai_planning_subtree/basic_ranged_attack_subtree,
+ /datum/ai_planning_subtree/basic_ranged_attack_subtree/hivebot_rapid,
/datum/ai_planning_subtree/attack_obstacle_in_path,
/datum/ai_planning_subtree/hive_communicate,
)
diff --git a/code/modules/mob/living/basic/space_fauna/netherworld/blankbody.dm b/code/modules/mob/living/basic/space_fauna/netherworld/blankbody.dm
index 5a7bb075f19..d49932fb704 100644
--- a/code/modules/mob/living/basic/space_fauna/netherworld/blankbody.dm
+++ b/code/modules/mob/living/basic/space_fauna/netherworld/blankbody.dm
@@ -26,22 +26,9 @@
lighting_cutoff_green = 15
lighting_cutoff_blue = 40
- ai_controller = /datum/ai_controller/basic_controller/blankbody
+ ai_controller = /datum/ai_controller/basic_controller/simple_hostile_obstacles
/mob/living/basic/blankbody/Initialize(mapload)
. = ..()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_NETHER, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 0)
AddComponent(/datum/component/health_scaling_effects, min_health_attack_modifier_lower = 8, min_health_attack_modifier_upper = 14)
-
-/datum/ai_controller/basic_controller/blankbody
- blackboard = list(
- BB_TARGETTING_DATUM = new /datum/targetting_datum/basic(),
- )
-
- ai_movement = /datum/ai_movement/basic_avoidance
- idle_behavior = /datum/idle_behavior/idle_random_walk
- planning_subtrees = list(
- /datum/ai_planning_subtree/simple_find_target,
- /datum/ai_planning_subtree/attack_obstacle_in_path,
- /datum/ai_planning_subtree/basic_melee_attack_subtree,
- )
diff --git a/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm b/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm
index b38ada0f6e1..cdde6ad05e4 100644
--- a/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm
+++ b/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm
@@ -27,7 +27,7 @@
lighting_cutoff_green = 25
lighting_cutoff_blue = 15
- ai_controller = /datum/ai_controller/basic_controller/creature
+ ai_controller = /datum/ai_controller/basic_controller/simple_hostile_obstacles
/mob/living/basic/creature/Initialize(mapload)
. = ..()
@@ -101,16 +101,3 @@
exit_jaunt(cast_on)
return
enter_jaunt(cast_on)
-
-/datum/ai_controller/basic_controller/creature
- blackboard = list(
- BB_TARGETTING_DATUM = new /datum/targetting_datum/basic(),
- )
-
- ai_movement = /datum/ai_movement/basic_avoidance
- idle_behavior = /datum/idle_behavior/idle_random_walk
- planning_subtrees = list(
- /datum/ai_planning_subtree/simple_find_target,
- /datum/ai_planning_subtree/attack_obstacle_in_path,
- /datum/ai_planning_subtree/basic_melee_attack_subtree,
- )
diff --git a/code/modules/mob/living/basic/space_fauna/netherworld/migo.dm b/code/modules/mob/living/basic/space_fauna/netherworld/migo.dm
index 18dca95013e..3f445ea1261 100644
--- a/code/modules/mob/living/basic/space_fauna/netherworld/migo.dm
+++ b/code/modules/mob/living/basic/space_fauna/netherworld/migo.dm
@@ -28,7 +28,7 @@
lighting_cutoff_green = 15
lighting_cutoff_blue = 50
- ai_controller = /datum/ai_controller/basic_controller/migo
+ ai_controller = /datum/ai_controller/basic_controller/simple_hostile_obstacles
var/static/list/migo_sounds
/// Odds migo will dodge
var/dodge_prob = 10
@@ -71,16 +71,3 @@
. = Move(get_step(loc,pick(cdir, ccdir)))
if(!.)//Can't dodge there so we just carry on
. = Move(moving_to, move_direction)
-
-/datum/ai_controller/basic_controller/migo
- blackboard = list(
- BB_TARGETTING_DATUM = new /datum/targetting_datum/basic(),
- )
-
- ai_movement = /datum/ai_movement/basic_avoidance
- idle_behavior = /datum/idle_behavior/idle_random_walk
- planning_subtrees = list(
- /datum/ai_planning_subtree/simple_find_target,
- /datum/ai_planning_subtree/attack_obstacle_in_path,
- /datum/ai_planning_subtree/basic_melee_attack_subtree,
- )
diff --git a/code/modules/mob/living/basic/space_fauna/paper_wizard/paper_wizard.dm b/code/modules/mob/living/basic/space_fauna/paper_wizard/paper_wizard.dm
index 3b32fbb4ce7..519e8ba1a73 100644
--- a/code/modules/mob/living/basic/space_fauna/paper_wizard/paper_wizard.dm
+++ b/code/modules/mob/living/basic/space_fauna/paper_wizard/paper_wizard.dm
@@ -110,8 +110,7 @@
faction = list(FACTION_STICKMAN)
melee_damage_lower = 1
melee_damage_upper = 5
-
- ai_controller = /datum/ai_controller/basic_controller/wizard_copy
+ ai_controller = /datum/ai_controller/basic_controller/simple_hostile
/mob/living/basic/paper_wizard/copy/Initialize(mapload)
. = ..()
@@ -141,18 +140,6 @@
new /obj/effect/temp_visual/small_smoke/halfsecond(get_turf(src))
qdel(src) //I see through your ruse!
-/datum/ai_controller/basic_controller/wizard_copy
- blackboard = list(
- BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
- )
-
- ai_movement = /datum/ai_movement/basic_avoidance
- idle_behavior = /datum/idle_behavior/idle_random_walk
- planning_subtrees = list(
- /datum/ai_planning_subtree/simple_find_target,
- /datum/ai_planning_subtree/basic_melee_attack_subtree,
- )
-
//fancy effects
/obj/effect/temp_visual/paper_scatter
name = "scattering paper"
diff --git a/code/modules/mob/living/simple_animal/friendly/robot_customer.dm b/code/modules/mob/living/basic/space_fauna/robot_customer.dm
similarity index 63%
rename from code/modules/mob/living/simple_animal/friendly/robot_customer.dm
rename to code/modules/mob/living/basic/space_fauna/robot_customer.dm
index 13eac2939f3..e084e11f403 100644
--- a/code/modules/mob/living/simple_animal/friendly/robot_customer.dm
+++ b/code/modules/mob/living/basic/space_fauna/robot_customer.dm
@@ -1,45 +1,56 @@
///Robot customers
-/mob/living/simple_animal/robot_customer
- name = "space-tourist bot"
+/mob/living/basic/robot_customer
+ name = "tourist bot"
maxHealth = 150
health = 150
desc = "I wonder what they'll order..."
gender = NEUTER
+
icon = 'icons/mob/simple/tourists.dmi'
icon_state = "amerifat"
icon_living = "amerifat"
- ///Override so it uses datum ai
- can_have_ai = FALSE
- AIStatus = AI_OFF
- del_on_death = TRUE
+
+ basic_mob_flags = DEL_ON_DEATH
mob_biotypes = MOB_ROBOTIC|MOB_HUMANOID
sentience_type = SENTIENCE_ARTIFICIAL
- ai_controller = /datum/ai_controller/robot_customer
+
unsuitable_atmos_damage = 0
- minbodytemp = 0
- maxbodytemp = 1000
+ minimum_survivable_temperature = TCMB
+ maximum_survivable_temperature = T0C + 1000
+
+ ai_controller = /datum/ai_controller/robot_customer
+
+ /// The clothes that we draw on this tourist.
var/clothes_set = "amerifat_clothes"
+ /// Reference to the hud that we show when the player hovers over us.
var/datum/atom_hud/hud_to_show_on_hover
-
-/mob/living/simple_animal/robot_customer/Initialize(mapload, datum/customer_data/customer_data = /datum/customer_data/american, datum/venue/attending_venue = SSrestaurant.all_venues[/datum/venue/restaurant])
- ADD_TRAIT(src, list(TRAIT_NOMOBSWAP, TRAIT_NO_TELEPORT, TRAIT_STRONG_GRABBER), INNATE_TRAIT) // never suffer a bitch to fuck with you
- AddElement(/datum/element/footstep, FOOTSTEP_OBJ_ROBOT, 1, -6, sound_vary = TRUE)
+/mob/living/basic/robot_customer/Initialize(
+ mapload,
+ datum/customer_data/customer_data = /datum/customer_data/american,
+ datum/venue/attending_venue = SSrestaurant.all_venues[/datum/venue/restaurant],
+)
var/datum/customer_data/customer_info = SSrestaurant.all_customers[customer_data]
- clothes_set = pick(customer_info.clothing_sets)
ai_controller = customer_info.ai_controller_used
+
. = ..()
+
+ ADD_TRAIT(src, list(TRAIT_NOMOBSWAP, TRAIT_NO_TELEPORT, TRAIT_STRONG_GRABBER), INNATE_TRAIT) // never suffer a bitch to fuck with you
+ AddElement(/datum/element/footstep, FOOTSTEP_OBJ_ROBOT, 1, -6, sound_vary = TRUE)
+
ai_controller.set_blackboard_key(BB_CUSTOMER_CUSTOMERINFO, customer_info)
ai_controller.set_blackboard_key(BB_CUSTOMER_ATTENDING_VENUE, attending_venue)
ai_controller.set_blackboard_key(BB_CUSTOMER_PATIENCE, customer_info.total_patience)
+
icon = customer_info.base_icon
icon_state = customer_info.base_icon_state
name = "[pick(customer_info.name_prefixes)]-bot"
color = rgb(rand(80,255), rand(80,255), rand(80,255))
- update_icon()
+ clothes_set = pick(customer_info.clothing_sets)
+ update_appearance(UPDATE_ICON)
///Clean up on the mobs seat etc when its deleted (Either by murder or because it left)
-/mob/living/simple_animal/robot_customer/Destroy()
+/mob/living/basic/robot_customer/Destroy()
var/datum/venue/attending_venue = ai_controller.blackboard[BB_CUSTOMER_ATTENDING_VENUE]
var/obj/structure/holosign/robot_seat/our_seat = ai_controller.blackboard[BB_CUSTOMER_MY_SEAT]
attending_venue.current_visitors -= src
@@ -49,18 +60,18 @@
return ..()
///Robots need robot gibs...!
-/mob/living/simple_animal/robot_customer/spawn_gibs()
+/mob/living/basic/robot_customer/spawn_gibs()
new /obj/effect/gibspawner/robot(drop_location(), src)
-/mob/living/simple_animal/robot_customer/MouseEntered(location, control, params)
+/mob/living/basic/robot_customer/MouseEntered(location, control, params)
. = ..()
hud_to_show_on_hover?.show_to(usr)
-/mob/living/simple_animal/robot_customer/MouseExited(location, control, params)
+/mob/living/basic/robot_customer/MouseExited(location, control, params)
. = ..()
hud_to_show_on_hover?.hide_from(usr)
-/mob/living/simple_animal/robot_customer/update_overlays()
+/mob/living/basic/robot_customer/update_overlays()
. = ..()
var/datum/customer_data/customer_info = ai_controller.blackboard[BB_CUSTOMER_CUSTOMERINFO]
@@ -82,21 +93,24 @@
if(bonus_overlays)
. += bonus_overlays
-/mob/living/simple_animal/robot_customer/send_speech(message, message_range, obj/source, bubble_type, list/spans, datum/language/message_language, list/message_mods, forced, tts_message, list/tts_filter)
+/mob/living/basic/robot_customer/send_speech(message, message_range, obj/source, bubble_type, list/spans, datum/language/message_language, list/message_mods, forced, tts_message, list/tts_filter)
. = ..()
var/datum/customer_data/customer_info = ai_controller.blackboard[BB_CUSTOMER_CUSTOMERINFO]
playsound(src, customer_info.speech_sound, 30, extrarange = MEDIUM_RANGE_SOUND_EXTRARANGE, falloff_distance = 5)
-/mob/living/simple_animal/robot_customer/examine(mob/user)
+/mob/living/basic/robot_customer/examine(mob/user)
. = ..()
- // this should be handled by the ai controller
- if(ai_controller.blackboard[BB_CUSTOMER_CURRENT_ORDER])
- var/datum/venue/attending_venue = ai_controller.blackboard[BB_CUSTOMER_ATTENDING_VENUE]
- var/wanted_item = ai_controller.blackboard[BB_CUSTOMER_CURRENT_ORDER]
- var/order
- if(istype(wanted_item, /datum/custom_order))
- var/datum/custom_order/custom_order = wanted_item
- order = custom_order.get_order_line(attending_venue)
- else
- order = attending_venue.order_food_line(wanted_item)
- . += span_notice("Their order was: \"[order].\"")
+ if(isnull(ai_controller.blackboard[BB_CUSTOMER_CURRENT_ORDER]))
+ return
+
+ var/datum/venue/attending_venue = ai_controller.blackboard[BB_CUSTOMER_ATTENDING_VENUE]
+ var/wanted_item = ai_controller.blackboard[BB_CUSTOMER_CURRENT_ORDER]
+ var/order = "nothing"
+
+ if(istype(wanted_item, /datum/custom_order))
+ var/datum/custom_order/custom_order = wanted_item
+ order = custom_order.get_order_line(attending_venue)
+ else
+ order = attending_venue.order_food_line(wanted_item)
+
+ . += span_notice("Their order was: \"[order].\"")
diff --git a/code/modules/mob/living/basic/space_fauna/snake/snake.dm b/code/modules/mob/living/basic/space_fauna/snake/snake.dm
new file mode 100644
index 00000000000..13b9a327cc5
--- /dev/null
+++ b/code/modules/mob/living/basic/space_fauna/snake/snake.dm
@@ -0,0 +1,86 @@
+
+/mob/living/basic/snake
+ name = "snake"
+ desc = "A slithery snake. These legless reptiles are the bane of mice and adventurers alike."
+ icon_state = "snake"
+ icon_living = "snake"
+ icon_dead = "snake_dead"
+ speak_emote = list("hisses")
+
+ health = 20
+ maxHealth = 20
+ melee_damage_lower = 5
+ melee_damage_upper = 6
+ obj_damage = 0
+ environment_smash = ENVIRONMENT_SMASH_NONE
+
+ attack_verb_continuous = "bites"
+ attack_verb_simple = "bite"
+ attack_sound = 'sound/weapons/bite.ogg'
+ attack_vis_effect = ATTACK_EFFECT_BITE
+
+ response_help_continuous = "pets"
+ response_help_simple = "pet"
+ response_disarm_continuous = "shoos"
+ response_disarm_simple = "shoo"
+ response_harm_continuous = "steps on"
+ response_harm_simple = "step on"
+
+ density = FALSE
+ pass_flags = PASSTABLE | PASSMOB
+ mob_size = MOB_SIZE_SMALL
+
+ faction = list(FACTION_HOSTILE)
+ mob_biotypes = MOB_ORGANIC | MOB_BEAST | MOB_REPTILE
+ gold_core_spawnable = FRIENDLY_SPAWN
+
+ ai_controller = /datum/ai_controller/basic_controller/snake
+
+ /// List of stuff (mice) that we want to eat
+ var/static/list/edibles = list(
+ /mob/living/basic/mouse,
+ /obj/item/food/deadmouse,
+ )
+
+/mob/living/basic/snake/Initialize(mapload, special_reagent)
+ . = ..()
+ ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
+
+ AddElement(/datum/element/ai_retaliate)
+ AddElement(/datum/element/swabable, CELL_LINE_TABLE_SNAKE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
+
+ AddElement(/datum/element/basic_eating, 2, 0, null, edibles)
+ ai_controller.set_blackboard_key(BB_BASIC_FOODS, edibles)
+
+ AddComponent(\
+ /datum/component/tameable,\
+ food_types = list(/obj/item/food/deadmouse),\
+ tame_chance = 75,\
+ bonus_tame_chance = 10,\
+ ) // snakes are really fond of food, especially in the cold darkness of space :)
+
+ if(isnull(special_reagent))
+ special_reagent = /datum/reagent/toxin
+
+ AddElement(/datum/element/venomous, special_reagent, 4)
+
+/mob/living/basic/snake/befriend(mob/living/new_friend)
+ . = ..()
+ visible_message("[src] hisses happily as it seems to bond with [new_friend].")
+
+/// Snakes are primarily concerned with getting those tasty, tasty mice, but aren't afraid to strike back at those who attack them
+/datum/ai_controller/basic_controller/snake
+ blackboard = list(
+ BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/not_friends/allow_items,
+ )
+
+ ai_traits = STOP_MOVING_WHEN_PULLED
+ ai_movement = /datum/ai_movement/basic_avoidance
+ idle_behavior = /datum/idle_behavior/idle_random_walk
+
+ planning_subtrees = list(
+ /datum/ai_planning_subtree/target_retaliate,
+ /datum/ai_planning_subtree/find_food,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
+ /datum/ai_planning_subtree/random_speech/snake,
+ )
diff --git a/code/modules/mob/living/basic/space_fauna/snake/snake_ai.dm b/code/modules/mob/living/basic/space_fauna/snake/snake_ai.dm
new file mode 100644
index 00000000000..3eb404761c5
--- /dev/null
+++ b/code/modules/mob/living/basic/space_fauna/snake/snake_ai.dm
@@ -0,0 +1,6 @@
+/datum/ai_planning_subtree/random_speech/snake
+ speech_chance = 5
+ speak = list("hsssss","sssSSsssss...","hiisssss")
+ sound = list('sound/creatures/snake_hissing1.ogg', 'sound/creatures/snake_hissing2.ogg')
+ emote_hear = list("hisses.")
+ emote_see = list("slithers around.", "glances.", "stares.")
diff --git a/code/modules/mob/living/basic/space_fauna/spider/young_spider/young_spider.dm b/code/modules/mob/living/basic/space_fauna/spider/young_spider/young_spider.dm
index 57b9da542b7..50ec85e342c 100644
--- a/code/modules/mob/living/basic/space_fauna/spider/young_spider/young_spider.dm
+++ b/code/modules/mob/living/basic/space_fauna/spider/young_spider/young_spider.dm
@@ -30,6 +30,7 @@
/datum/ai_controller/basic_controller/young_spider
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic(),
+ BB_BASIC_MOB_FLEE_DISTANCE = 6,
)
ai_traits = STOP_MOVING_WHEN_PULLED
@@ -46,6 +47,3 @@
/datum/ai_planning_subtree/find_unwebbed_turf,
/datum/ai_planning_subtree/spin_web,
)
-
-/datum/ai_behavior/run_away_from_target/young_spider
- run_distance = 6
diff --git a/code/modules/mob/living/basic/vermin/mouse.dm b/code/modules/mob/living/basic/vermin/mouse.dm
index 0b3645b3e0f..46e175c5323 100644
--- a/code/modules/mob/living/basic/vermin/mouse.dm
+++ b/code/modules/mob/living/basic/vermin/mouse.dm
@@ -51,7 +51,7 @@
held_state = "mouse_[body_color]" // not handled by variety element
AddElement(/datum/element/animal_variety, "mouse", body_color, FALSE)
AddElement(/datum/element/swabable, CELL_LINE_TABLE_MOUSE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 10)
- AddComponent(/datum/component/squeak, list('sound/effects/mousesqueek.ogg' = 1), 100, extrarange = SHORT_RANGE_SOUND_EXTRARANGE) //as quiet as a mouse or whatever
+ AddComponent(/datum/component/squeak, list('sound/creatures/mousesqueek.ogg' = 1), 100, extrarange = SHORT_RANGE_SOUND_EXTRARANGE) //as quiet as a mouse or whatever
var/static/list/loc_connections = list(
COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
)
@@ -381,6 +381,7 @@
BB_CURRENT_HUNTING_TARGET = null, // cheese
BB_LOW_PRIORITY_HUNTING_TARGET = null, // cable
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic(), // Use this to find people to run away from
+ BB_BASIC_MOB_FLEE_DISTANCE = 3,
)
ai_traits = STOP_MOVING_WHEN_PULLED
@@ -400,9 +401,6 @@
)
/// Don't look for anything to run away from if you are distracted by being adjacent to cheese
-/datum/ai_planning_subtree/flee_target/mouse
- flee_behaviour = /datum/ai_behavior/run_away_from_target/mouse
-
/datum/ai_planning_subtree/flee_target/mouse
/datum/ai_planning_subtree/flee_target/mouse/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
@@ -411,11 +409,6 @@
return // We see some cheese, which is more important than our life
return ..()
-/datum/ai_planning_subtree/flee_target/mouse/select
-
-/datum/ai_behavior/run_away_from_target/mouse
- run_distance = 3 // Mostly exists in small tunnels, don't get ahead of yourself
-
/// AI controller for rats, slightly more complex than mice becuase they attack people
/datum/ai_controller/basic_controller/mouse/rat
blackboard = list(
diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm
index e182c51f54f..b63ca68d7d7 100644
--- a/code/modules/mob/living/brain/MMI.dm
+++ b/code/modules/mob/living/brain/MMI.dm
@@ -268,7 +268,7 @@
if(user)
to_chat(user, span_warning("\The [src] indicates that there is no mind present!"))
return FALSE
- if(brain.decoy_override)
+ if(brain?.decoy_override)
if(user)
to_chat(user, span_warning("This [name] does not seem to fit!"))
return FALSE
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index 4bd275b5df1..10cff8c19ac 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -39,6 +39,21 @@
/// Maximum skillchip slots available. Do not reference this var directly and instead call get_max_skillchip_slots()
var/max_skillchip_slots = 5
+ /// Size modifier for the sprite
+ var/brain_size = 1
+
+/obj/item/organ/internal/brain/Initialize(mapload)
+ . = ..()
+ // Brain size logic
+ transform = transform.Scale(brain_size)
+
+/obj/item/organ/internal/brain/examine()
+ . = ..()
+ if(brain_size < 1)
+ . += span_notice("It is a bit on the smaller side...")
+ if(brain_size > 1)
+ . += span_notice("It is bigger than average...")
+
/obj/item/organ/internal/brain/Insert(mob/living/carbon/brain_owner, special = FALSE, drop_if_replaced = TRUE, no_id_transfer = FALSE)
. = ..()
if(!.)
@@ -406,6 +421,9 @@
. = ..()
organ_owner.gain_trauma(/datum/brain_trauma/special/bluespace_prophet, TRAUMA_RESILIENCE_ABSOLUTE)
+/obj/item/organ/internal/brain/felinid //A bit smaller than average
+ brain_size = 0.8
+
////////////////////////////////////TRAUMAS////////////////////////////////////////
/obj/item/organ/internal/brain/proc/has_trauma_type(brain_trauma_type = /datum/brain_trauma, resilience = TRAUMA_RESILIENCE_ABSOLUTE)
@@ -553,4 +571,4 @@
var/obj/item/organ/internal/brain/old_brain = new_owner.get_organ_slot(ORGAN_SLOT_BRAIN)
old_brain.Remove(new_owner, special = TRUE, no_id_transfer = TRUE)
qdel(old_brain)
- Insert(new_owner, special = TRUE, drop_if_replaced = FALSE, no_id_transfer = TRUE)
+ return Insert(new_owner, special = TRUE, drop_if_replaced = FALSE, no_id_transfer = TRUE)
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 8b97685d0a8..789a459b492 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -57,6 +57,13 @@
return null
+/mob/living/carbon/is_ears_covered()
+ for(var/obj/item/worn_thing as anything in get_equipped_items())
+ if(worn_thing.flags_cover & EARS_COVERED)
+ return worn_thing
+
+ return null
+
/mob/living/carbon/check_projectile_dismemberment(obj/projectile/P, def_zone)
var/obj/item/bodypart/affecting = get_bodypart(def_zone)
if(affecting && !(affecting.bodypart_flags & BODYPART_UNREMOVABLE) && affecting.get_damage() >= (affecting.max_damage - P.dismemberment))
diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm
index 17718190ba5..6a8fc967cb5 100644
--- a/code/modules/mob/living/carbon/human/_species.dm
+++ b/code/modules/mob/living/carbon/human/_species.dm
@@ -449,6 +449,13 @@ GLOBAL_LIST_EMPTY(features_by_species)
wearer.hud_used?.update_locked_slots()
worn_items_fit_body_check(wearer)
+/**
+ * Normalizes blood in a human if it is excessive. If it is above BLOOD_VOLUME_NORMAL, this will clamp it to that value. It will not give the human more blodo than they have less than this value.
+ */
+/datum/species/proc/normalize_blood(mob/living/carbon/human/blood_possessing_human)
+ var/normalized_blood_values = max(blood_possessing_human.blood_volume, 0, BLOOD_VOLUME_NORMAL)
+ blood_possessing_human.blood_volume = normalized_blood_values
+
/**
* Proc called when a carbon becomes this species.
*
@@ -459,34 +466,37 @@ GLOBAL_LIST_EMPTY(features_by_species)
* * old_species - The species that the carbon used to be before becoming this race, used for regenerating organs.
* * pref_load - Preferences to be loaded from character setup, loads in preferred mutant things like bodyparts, digilegs, skin color, etc.
*/
-/datum/species/proc/on_species_gain(mob/living/carbon/human/C, datum/species/old_species, pref_load)
+/datum/species/proc/on_species_gain(mob/living/carbon/human/human_who_gained_species, datum/species/old_species, pref_load)
SHOULD_CALL_PARENT(TRUE)
// Drop the items the new species can't wear
- if(C.hud_used)
- C.hud_used.update_locked_slots()
+ if(human_who_gained_species.hud_used)
+ human_who_gained_species.hud_used.update_locked_slots()
- C.mob_biotypes = inherent_biotypes
- C.mob_respiration_type = inherent_respiration_type
- C.butcher_results = knife_butcher_results?.Copy()
+ human_who_gained_species.mob_biotypes = inherent_biotypes
+ human_who_gained_species.mob_respiration_type = inherent_respiration_type
+ human_who_gained_species.butcher_results = knife_butcher_results?.Copy()
if(old_species.type != type)
- replace_body(C, src)
+ replace_body(human_who_gained_species, src)
- regenerate_organs(C, old_species, visual_only = C.visual_only_organs)
+ regenerate_organs(human_who_gained_species, old_species, visual_only = human_who_gained_species.visual_only_organs)
// Drop the items the new species can't wear
- INVOKE_ASYNC(src, PROC_REF(worn_items_fit_body_check), C, TRUE)
+ INVOKE_ASYNC(src, PROC_REF(worn_items_fit_body_check), human_who_gained_species, TRUE)
//Assigns exotic blood type if the species has one
- if(exotic_bloodtype && C.dna.blood_type != exotic_bloodtype)
- C.dna.blood_type = exotic_bloodtype
+ if(exotic_bloodtype && human_who_gained_species.dna.blood_type != exotic_bloodtype)
+ human_who_gained_species.dna.blood_type = exotic_bloodtype
//Otherwise, check if the previous species had an exotic bloodtype and we do not have one and assign a random blood type
//(why the fuck is blood type not tied to a fucking DNA block?)
else if(old_species.exotic_bloodtype && !exotic_bloodtype)
- C.dna.blood_type = random_blood_type()
+ human_who_gained_species.dna.blood_type = random_blood_type()
- if(ishuman(C))
- var/mob/living/carbon/human/human = C
+ //Resets blood if it is excessively high for some reason
+ normalize_blood(human_who_gained_species)
+
+ if(ishuman(human_who_gained_species))
+ var/mob/living/carbon/human/human = human_who_gained_species
for(var/obj/item/organ/external/organ_path as anything in external_organs)
if(!should_external_organ_apply_to(organ_path, human))
continue
@@ -495,25 +505,27 @@ GLOBAL_LIST_EMPTY(features_by_species)
var/obj/item/organ/external/new_organ = SSwardrobe.provide_type(organ_path)
new_organ.Insert(human, special=TRUE, drop_if_replaced=FALSE)
+
+
if(length(inherent_traits))
- C.add_traits(inherent_traits, SPECIES_TRAIT)
+ human_who_gained_species.add_traits(inherent_traits, SPECIES_TRAIT)
if(inherent_factions)
for(var/i in inherent_factions)
- C.faction += i //Using +=/-= for this in case you also gain the faction from a different source.
+ human_who_gained_species.faction += i //Using +=/-= for this in case you also gain the faction from a different source.
// All languages associated with this language holder are added with source [LANGUAGE_SPECIES]
// rather than source [LANGUAGE_ATOM], so we can track what to remove if our species changes again
var/datum/language_holder/gaining_holder = GLOB.prototype_language_holders[species_language_holder]
for(var/language in gaining_holder.understood_languages)
- C.grant_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_SPECIES)
+ human_who_gained_species.grant_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_SPECIES)
for(var/language in gaining_holder.spoken_languages)
- C.grant_language(language, SPOKEN_LANGUAGE, LANGUAGE_SPECIES)
+ human_who_gained_species.grant_language(language, SPOKEN_LANGUAGE, LANGUAGE_SPECIES)
for(var/language in gaining_holder.blocked_languages)
- C.add_blocked_language(language, LANGUAGE_SPECIES)
- C.regenerate_icons()
+ human_who_gained_species.add_blocked_language(language, LANGUAGE_SPECIES)
+ human_who_gained_species.regenerate_icons()
- SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species)
+ SEND_SIGNAL(human_who_gained_species, COMSIG_SPECIES_GAIN, src, old_species)
properly_gained = TRUE
@@ -1484,7 +1496,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
*/
/datum/species/proc/handle_body_temperature(mob/living/carbon/human/humi, seconds_per_tick, times_fired)
//when in a cryo unit we suspend all natural body regulation
- if(istype(humi.loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
+ if(istype(humi.loc, /obj/machinery/cryo_cell))
return
//Only stabilise core temp when alive and not in statis
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 40e4bf095d5..680e5c14f7e 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -372,7 +372,7 @@
var/obj/item/bodypart/the_part = isbodypart(target_zone) ? target_zone : get_bodypart(check_zone(target_zone)) //keep these synced
// Loop through the clothing covering this bodypart and see if there's any thiccmaterials
if(!(injection_flags & INJECT_CHECK_PENETRATE_THICK))
- for(var/obj/item/clothing/iter_clothing in clothingonpart(the_part))
+ for(var/obj/item/clothing/iter_clothing in get_clothing_on_part(the_part))
if(iter_clothing.clothing_flags & THICKMATERIAL)
. = FALSE
break
@@ -786,6 +786,7 @@
VV_DROPDOWN_OPTION(VV_HK_MOD_QUIRKS, "Add/Remove Quirks")
VV_DROPDOWN_OPTION(VV_HK_SET_SPECIES, "Set Species")
VV_DROPDOWN_OPTION(VV_HK_PURRBATION, "Toggle Purrbation")
+ VV_DROPDOWN_OPTION(VV_HK_APPLY_DNA_INFUSION, "Apply DNA Infusion")
/mob/living/carbon/human/vv_do_topic(list/href_list)
. = ..()
@@ -871,6 +872,19 @@
var/msg = span_notice("[key_name_admin(usr)] has removed [key_name(src)] from purrbation.")
message_admins(msg)
admin_ticket_log(src, msg)
+ if(href_list[VV_HK_APPLY_DNA_INFUSION])
+ if(!check_rights(R_SPAWN))
+ return
+ if(!ishuman(src))
+ to_chat(usr, "This can only be done to human species.")
+ return
+ var/result = usr.client.grant_dna_infusion(src)
+ if(result)
+ to_chat(usr, "Successfully applied DNA Infusion [result] to [src].")
+ log_admin("[key_name(usr)] has applied DNA Infusion [result] to [key_name(src)].")
+ else
+ to_chat(usr, "Failed to apply DNA Infusion to [src].")
+ log_admin("[key_name(usr)] failed to apply a DNA Infusion to [key_name(src)].")
/mob/living/carbon/human/limb_attack_self()
var/obj/item/bodypart/arm = hand_bodyparts[active_hand_index]
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index bc951d49bb7..b02aaf03b17 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -6,21 +6,21 @@
if(isbodypart(def_zone))
var/obj/item/bodypart/bp = def_zone
if(bp)
- return checkarmor(def_zone, type)
+ return check_armor(def_zone, type)
var/obj/item/bodypart/affecting = get_bodypart(check_zone(def_zone))
if(affecting)
- return checkarmor(affecting, type)
+ return check_armor(affecting, type)
//If a specific bodypart is targetted, check how that bodypart is protected and return the value.
//If you don't specify a bodypart, it checks ALL your bodyparts for protection, and averages out the values
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
- armorval += checkarmor(BP, type)
+ armorval += check_armor(BP, type)
organnum++
return (armorval/max(organnum, 1))
-/mob/living/carbon/human/proc/checkarmor(obj/item/bodypart/def_zone, damage_type)
+/mob/living/carbon/human/proc/check_armor(obj/item/bodypart/def_zone, damage_type)
if(!damage_type)
return 0
var/protection = 100
@@ -32,7 +32,7 @@
return 100 - protection
///Get all the clothing on a specific body part
-/mob/living/carbon/human/proc/clothingonpart(obj/item/bodypart/def_zone)
+/mob/living/carbon/human/proc/get_clothing_on_part(obj/item/bodypart/def_zone)
var/list/covering_part = list()
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, ears, wear_id, wear_neck) //Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor)
for(var/bp in body_parts)
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index c91fc7d6638..2e061d32a6b 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -100,7 +100,7 @@
/// Environment handlers for species
/mob/living/carbon/human/handle_environment(datum/gas_mixture/environment, seconds_per_tick, times_fired)
// If we are in a cryo bed do not process life functions
- if(istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
+ if(istype(loc, /obj/machinery/cryo_cell))
return
dna.species.handle_environment(src, environment, seconds_per_tick, times_fired)
diff --git a/code/modules/mob/living/carbon/human/species_types/abominations.dm b/code/modules/mob/living/carbon/human/species_types/abominations.dm
index b7be74565ac..43ca71311c2 100644
--- a/code/modules/mob/living/carbon/human/species_types/abominations.dm
+++ b/code/modules/mob/living/carbon/human/species_types/abominations.dm
@@ -3,6 +3,7 @@
name = "\improper Tall Boy"
id = SPECIES_TALLBOY
examine_limb_id = SPECIES_HUMAN
+ changesource_flags = MIRROR_BADMIN | WABBAJACK
bodypart_overrides = list(
BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left,
BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right,
@@ -13,8 +14,10 @@
)
/datum/species/monkey/human_legged
+ name = "human-legged monkey"
id = SPECIES_MONKEY_HUMAN_LEGGED
examine_limb_id = SPECIES_MONKEY
+ changesource_flags = MIRROR_BADMIN | WABBAJACK
bodypart_overrides = list(
BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/monkey,
BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right/monkey,
@@ -25,8 +28,10 @@
)
/datum/species/monkey/monkey_freak
+ name = "human-armed monkey"
id = SPECIES_MONKEY_FREAK
examine_limb_id = SPECIES_MONKEY
+ changesource_flags = MIRROR_BADMIN | WABBAJACK
bodypart_overrides = list(
BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left,
BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right,
diff --git a/code/modules/mob/living/carbon/human/species_types/felinid.dm b/code/modules/mob/living/carbon/human/species_types/felinid.dm
index 793da47c05b..c8e14a6afd1 100644
--- a/code/modules/mob/living/carbon/human/species_types/felinid.dm
+++ b/code/modules/mob/living/carbon/human/species_types/felinid.dm
@@ -4,6 +4,7 @@
id = SPECIES_FELINE
examine_limb_id = SPECIES_HUMAN
mutant_bodyparts = list("ears" = "Cat", "wings" = "None")
+ mutantbrain = /obj/item/organ/internal/brain/felinid
mutanttongue = /obj/item/organ/internal/tongue/cat
/* SKYRAT EDIT REMOVAL - CUSTOMIZATION
mutantears = /obj/item/organ/internal/ears/cat
@@ -23,8 +24,6 @@
family_heirlooms = list(/obj/item/toy/cattoy)
/// When false, this is a felinid created by mass-purrbation
var/original_felinid = TRUE
- /// Brain size for scaling
- var/brain_size = 0.8
// Prevents felinids from taking toxin damage from carpotoxin
/datum/species/human/felinid/handle_chemical(datum/reagent/chem, mob/living/carbon/human/affected, seconds_per_tick, times_fired)
@@ -47,16 +46,6 @@
ears.Insert(target_human, drop_if_replaced = FALSE)
else
mutantears = /obj/item/organ/internal/ears
- var/obj/item/organ/internal/brain/current_brain = target_human.get_organ_by_type(/obj/item/organ/internal/brain)
- if(current_brain)
- current_brain.transform = current_brain.transform.Scale(brain_size) //smaller brain
- return ..()
-
-/datum/species/human/felinid/on_species_loss(mob/living/carbon/former_feline, datum/species/old_species, pref_load)
- if(iscarbon(former_feline))
- var/obj/item/organ/internal/brain/current_brain = former_feline.get_organ_by_type(/obj/item/organ/internal/brain)
- if(current_brain)
- current_brain.transform = current_brain.transform.Scale(1 / brain_size) //bigger brain
return ..()
/datum/species/human/felinid/randomize_features(mob/living/carbon/human/human_mob)
diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm
index 2c997274ffb..9db5a3253eb 100644
--- a/code/modules/mob/living/carbon/human/species_types/humans.dm
+++ b/code/modules/mob/living/carbon/human/species_types/humans.dm
@@ -18,7 +18,7 @@
human_mob.skin_tone = random_skin_tone()
/datum/species/human/get_scream_sound(mob/living/carbon/human/human)
- if(human.gender == MALE)
+ if(human.physique == MALE)
if(prob(1))
return 'sound/voice/human/wilhelm_scream.ogg'
return pick(
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index e66d72a2c44..990f27f0707 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -579,6 +579,9 @@
if(stat != DEAD) // If you are dead your body does not stabilize naturally
natural_bodytemperature_stabilization(environment, seconds_per_tick, times_fired)
+ else if(!on_fire && areatemp < bodytemperature) // lowers your dead body temperature to room temperature over time
+ adjust_bodytemperature((areatemp - bodytemperature), use_insulation=FALSE, use_steps=TRUE)
+
if(!on_fire || areatemp > bodytemperature) // If we are not on fire or the area is hotter
adjust_bodytemperature((areatemp - bodytemperature), use_insulation=TRUE, use_steps=TRUE)
diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm
index cb4d4a8241a..532d37ed1b2 100644
--- a/code/modules/mob/living/emote.dm
+++ b/code/modules/mob/living/emote.dm
@@ -193,7 +193,7 @@
return
var/mob/living/carbon/human/human_user = user
if(human_user.dna.species.id == SPECIES_HUMAN && !HAS_MIND_TRAIT(human_user, TRAIT_MIMING))
- if(human_user.gender == FEMALE)
+ if(human_user.physique == FEMALE)
return pick('sound/voice/human/gasp_female1.ogg', 'sound/voice/human/gasp_female2.ogg', 'sound/voice/human/gasp_female3.ogg')
else
return pick('sound/voice/human/gasp_male1.ogg', 'sound/voice/human/gasp_male2.ogg')
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 17c6d7faa9c..0d309ff10c9 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -88,6 +88,11 @@
/mob/living/proc/is_pepper_proof(check_flags = ALL)
return null
+/// Checks if the mob's ears (BOTH EARS, BOWMANS NEED NOT APPLY) are covered by something.
+/// Returns the atom covering the mob's ears, or null if their ears are uncovered.
+/mob/living/proc/is_ears_covered()
+ return null
+
/mob/living/proc/on_hit(obj/projectile/P)
return BULLET_ACT_HIT
diff --git a/code/modules/mob/living/living_say.dm b/code/modules/mob/living/living_say.dm
index b3f842e6a25..3a09256ee69 100644
--- a/code/modules/mob/living/living_say.dm
+++ b/code/modules/mob/living/living_say.dm
@@ -394,13 +394,29 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list(
tts_message_to_use = message_raw
var/list/filter = list()
+ var/list/special_filter = list()
+ var/voice_to_use = voice
+ var/use_radio = FALSE
if(length(voice_filter) > 0)
filter += voice_filter
if(length(tts_filter) > 0)
filter += tts_filter.Join(",")
-
- INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), src, html_decode(tts_message_to_use), message_language, voice, filter.Join(","), listened, message_range = message_range, pitch = pitch, silicon = tts_silicon_voice_effect)
+ if(ishuman(src))
+ var/mob/living/carbon/human/human_speaker = src
+ if(human_speaker.wear_mask)
+ var/obj/item/clothing/mask/worn_mask = human_speaker.wear_mask
+ if(worn_mask.voice_override)
+ voice_to_use = worn_mask.voice_override
+ if(worn_mask.voice_filter)
+ filter += worn_mask.voice_filter
+ use_radio = worn_mask.use_radio_beeps_tts
+ if(use_radio)
+ special_filter += TTS_FILTER_RADIO
+ if(issilicon(src))
+ special_filter += TTS_FILTER_SILICON
+
+ INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), src, html_decode(tts_message_to_use), message_language, voice_to_use, filter.Join(","), listened, message_range = message_range, pitch = pitch, special_filters = special_filter.Join("|"))
var/image/say_popup = image('icons/mob/effects/talk.dmi', src, "[bubble_type][talk_icon_state]", FLY_LAYER)
SET_PLANE_EXPLICIT(say_popup, ABOVE_GAME_PLANE, src)
diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm
index 277b36c274b..f820d3ca1cf 100644
--- a/code/modules/mob/living/silicon/robot/robot_defense.dm
+++ b/code/modules/mob/living/silicon/robot/robot_defense.dm
@@ -439,11 +439,8 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real
if(prob(75) && Proj.damage > 0)
spark_system.start()
-/mob/living/silicon/on_hit(obj/projectile/P)
- if(!has_movespeed_modifier(/datum/movespeed_modifier/borg_throw))
- add_movespeed_modifier(/datum/movespeed_modifier/borg_throw)
- addtimer(CALLBACK(src, TYPE_PROC_REF(/mob/living/silicon, clear_throw_slowdown)), (P.throwforce / 10) SECONDS)
- return ..()
-
-/mob/living/silicon/proc/clear_throw_slowdown()
- src.remove_movespeed_modifier(/datum/movespeed_modifier/borg_throw)
+/mob/living/silicon/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
+ . = ..()
+ if (. || AM.throwforce < CYBORG_THROW_SLOWDOWN_THRESHOLD)
+ return
+ apply_status_effect(/datum/status_effect/borg_throw_slow)
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index bf785954fe7..7bd48ab62fb 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -104,8 +104,6 @@
var/reset_access_timer_id
var/ignorelistcleanuptimer = 1 // This ticks up every automated action, at 300 we clean the ignore list
- /// Component which allows ghosts to take over this bot
- var/datum/component/ghost_direct_control/personality_download
/// If true we will allow ghosts to control this mob
var/can_be_possessed = FALSE
/// If true we will offer this
@@ -212,7 +210,6 @@
GLOB.bots_list -= src
QDEL_NULL(paicard)
QDEL_NULL(pa_system)
- QDEL_NULL(personality_download)
QDEL_NULL(internal_radio)
QDEL_NULL(access_card)
QDEL_NULL(path_hud)
@@ -225,14 +222,14 @@
return
can_be_possessed = TRUE
var/can_announce = !mapload && COOLDOWN_FINISHED(src, offer_ghosts_cooldown)
- personality_download = AddComponent(\
- /datum/component/ghost_direct_control,\
- ban_type = ROLE_BOT,\
- poll_candidates = can_announce,\
- poll_ignore_key = POLL_IGNORE_BOTS,\
- assumed_control_message = (bot_cover_flags & BOT_COVER_EMAGGED) ? get_emagged_message() : possessed_message,\
- extra_control_checks = CALLBACK(src, PROC_REF(check_possession)),\
- after_assumed_control = CALLBACK(src, PROC_REF(post_possession)),\
+ AddComponent(
+ /datum/component/ghost_direct_control, \
+ ban_type = ROLE_BOT, \
+ poll_candidates = can_announce, \
+ poll_ignore_key = POLL_IGNORE_BOTS, \
+ assumed_control_message = (bot_cover_flags & BOT_COVER_EMAGGED) ? get_emagged_message() : possessed_message, \
+ extra_control_checks = CALLBACK(src, PROC_REF(check_possession)), \
+ after_assumed_control = CALLBACK(src, PROC_REF(post_possession)), \
)
if (can_announce)
COOLDOWN_START(src, offer_ghosts_cooldown, 30 SECONDS)
@@ -240,7 +237,7 @@
/// Disables this bot from being possessed by ghosts
/mob/living/simple_animal/bot/proc/disable_possession(mob/user)
can_be_possessed = FALSE
- QDEL_NULL(personality_download)
+ qdel(GetComponent(/datum/component/ghost_direct_control))
if (isnull(key))
return
if (user)
diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm
index b392417aab2..2d17820af0b 100644
--- a/code/modules/mob/living/simple_animal/hostile/alien.dm
+++ b/code/modules/mob/living/simple_animal/hostile/alien.dm
@@ -32,7 +32,7 @@
lighting_cutoff_red = 30
lighting_cutoff_green = 15
lighting_cutoff_blue = 50
- unique_name = 1
+ unique_name = TRUE
gold_core_spawnable = NO_SPAWN
death_sound = 'sound/voice/hiss6.ogg'
death_message = "lets out a waning guttural screech, green blood bubbling from its maw..."
@@ -91,7 +91,7 @@
projectiletype = /obj/projectile/neurotoxin/damaging
projectilesound = 'sound/weapons/pierce.ogg'
status_flags = 0
- unique_name = 0
+ unique_name = FALSE
var/sterile = 1
var/plants_off = 0
var/egg_cooldown = 30
diff --git a/code/modules/mob/living/simple_animal/hostile/constructs/constructs.dm b/code/modules/mob/living/simple_animal/hostile/constructs/constructs.dm
index 124b797d0da..23f7590dc8e 100644
--- a/code/modules/mob/living/simple_animal/hostile/constructs/constructs.dm
+++ b/code/modules/mob/living/simple_animal/hostile/constructs/constructs.dm
@@ -28,7 +28,7 @@
maxbodytemp = INFINITY
faction = list(FACTION_CULT)
pressure_resistance = 100
- unique_name = 1
+ unique_name = TRUE
AIStatus = AI_OFF //normal constructs don't have AI
loot = list(/obj/item/ectoplasm)
del_on_death = TRUE
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
index 745a48c948c..828a78ccfb1 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
@@ -436,7 +436,7 @@ Difficulty: Hard
/mob/living/simple_animal/hostile/megafauna/hierophant/CanAttack(atom/the_target)
. = ..()
- if(istype(the_target, /mob/living/simple_animal/hostile/asteroid/hivelordbrood)) //ignore temporary targets in favor of more permanent targets
+ if(istype(the_target, /mob/living/basic/legion_brood)) //ignore temporary targets in favor of more permanent targets
return FALSE
/mob/living/simple_animal/hostile/megafauna/hierophant/GiveTarget(new_target)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
index 05695daf59a..777cb3b878f 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
@@ -141,10 +141,9 @@
///Attack proc. Spawns a singular legion skull.
/mob/living/simple_animal/hostile/megafauna/legion/proc/create_legion_skull()
- var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/A = new(loc)
- A.GiveTarget(target)
- A.friends = friends
- A.faction = faction
+ var/mob/living/basic/legion_brood/minion = new(loc)
+ minion.assign_creator(src)
+ minion.ai_controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] = target
//CHARGE
@@ -210,7 +209,7 @@
var/mob/living/living_target = target
switch(living_target.stat)
if(UNCONSCIOUS, HARD_CRIT)
- var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/legion = new(loc)
+ var/mob/living/basic/legion_brood/legion = new(loc)
legion.infest(living_target)
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm
index 4cb4d97f38f..bf4d33a10ed 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm
@@ -249,7 +249,8 @@
/obj/projectile/herald/teleshot/on_hit(atom/target, blocked = FALSE)
. = ..()
- firer.forceMove(get_turf(src))
+ if(!QDELETED(firer))
+ firer.forceMove(get_turf(src))
//Herald's loot: Cloak of the Prophet
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm
index a705e11465b..ec6c843080c 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm
@@ -328,10 +328,9 @@
/obj/item/crusher_trophy/legionnaire_spine/on_mark_detonation(mob/living/target, mob/living/user)
if(!prob(bonus_value) || target.stat == DEAD)
return
- var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/A = new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion(user.loc)
- A.GiveTarget(target)
- A.friends += user
- A.faction = user.faction.Copy()
+ var/mob/living/basic/legion_brood/minion = new (user.loc)
+ minion.assign_creator(user)
+ minion.ai_controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] = target
/obj/item/crusher_trophy/legionnaire_spine/attack_self(mob/user)
if(!isliving(user))
@@ -342,9 +341,9 @@
to_chat(LivingUser, "You need to wait longer to use this again.")
return
LivingUser.visible_message(span_boldwarning("[LivingUser] shakes the [src] and summons a legion skull!"))
- var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/LegionSkull = new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion(LivingUser.loc)
- LegionSkull.friends += LivingUser
- LegionSkull.faction = LivingUser.faction.Copy()
+
+ var/mob/living/basic/legion_brood/minion = new (LivingUser.loc)
+ minion.assign_creator(LivingUser)
next_use_time = world.time + 4 SECONDS
#undef LEGIONNAIRE_CHARGE
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
deleted file mode 100644
index 2d92ef88a65..00000000000
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
+++ /dev/null
@@ -1,333 +0,0 @@
-/mob/living/simple_animal/hostile/asteroid/hivelord
- name = "hivelord"
- desc = "A levitating swarm of tiny creatures which act as a single individual. When threatened or hunting they rapidly replicate additional short-lived bodies."
- icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
- icon_state = "hivelord"
- icon_living = "hivelord"
- icon_aggro = "hivelord_alert"
- icon_dead = "hivelord_dead"
- icon_gib = "syndicate_gib"
- mob_biotypes = MOB_ORGANIC
- move_to_delay = 14
- ranged = 1
- vision_range = 5
- aggro_vision_range = 9
- speed = 3
- maxHealth = 75
- health = 75
- harm_intent_damage = 5
- melee_damage_lower = 0
- melee_damage_upper = 0
- attack_verb_continuous = "weakly tackles"
- attack_verb_simple = "weakly tackles"
- speak_emote = list("telepathically cries")
- attack_sound = 'sound/weapons/pierce.ogg'
- throw_message = "passes between the bodies of the"
- ranged_cooldown = 0
- ranged_cooldown_time = 20
- obj_damage = 0
- environment_smash = ENVIRONMENT_SMASH_NONE
- retreat_distance = 3
- minimum_distance = 3
- pass_flags = PASSTABLE
- loot = list(/obj/item/organ/internal/monster_core/regenerative_core)
- var/brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood
- var/has_clickbox = TRUE
-
-/mob/living/simple_animal/hostile/asteroid/hivelord/Initialize(mapload)
- . = ..()
- if(has_clickbox)
- AddComponent(/datum/component/clickbox, icon_state = "hivelord", max_scale = INFINITY, dead_state = "hivelord_dead") //they writhe so much.
-
-/mob/living/simple_animal/hostile/asteroid/hivelord/OpenFire(the_target)
- if(world.time < ranged_cooldown)
- return
- var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/brood = new brood_type(src.loc)
- brood.flags_1 |= (flags_1 & ADMIN_SPAWNED_1)
- brood.GiveTarget(target)
- brood.friends = friends
- brood.faction = faction.Copy()
- ranged_cooldown = world.time + ranged_cooldown_time
-
-/mob/living/simple_animal/hostile/asteroid/hivelord/AttackingTarget()
- OpenFire()
- return TRUE
-
-/mob/living/simple_animal/hostile/asteroid/hivelord/death(gibbed)
- mouse_opacity = MOUSE_OPACITY_ICON
- return ..()
-
-//A fragile but rapidly produced creature
-/mob/living/simple_animal/hostile/asteroid/hivelordbrood
- name = "hivelord brood"
- desc = "Short-lived attack form of the hivelord. One isn't much of a threat, but..."
- icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
- icon_state = "hivelord_brood"
- icon_living = "hivelord_brood"
- icon_aggro = "hivelord_brood"
- icon_dead = "hivelord_brood"
- icon_gib = "syndicate_gib"
- move_to_delay = 1
- friendly_verb_continuous = "buzzes near"
- friendly_verb_simple = "buzz near"
- vision_range = 10
- speed = 3
- maxHealth = 1
- health = 1
- harm_intent_damage = 5
- melee_damage_lower = 2
- melee_damage_upper = 2
- attack_verb_continuous = "slashes"
- attack_verb_simple = "slash"
- speak_emote = list("telepathically cries")
- attack_sound = 'sound/weapons/pierce.ogg'
- attack_vis_effect = ATTACK_EFFECT_SLASH
- throw_message = "falls right through the strange body of the"
- obj_damage = 0
- environment_smash = ENVIRONMENT_SMASH_NONE
- pass_flags = PASSTABLE | PASSMOB
- density = FALSE
- del_on_death = 1
- var/clickbox_state = "hivelord"
- var/clickbox_max_scale = INFINITY
-
-/mob/living/simple_animal/hostile/asteroid/hivelordbrood/Initialize(mapload)
- . = ..()
- addtimer(CALLBACK(src, PROC_REF(death)), 10 SECONDS)
- AddElement(/datum/element/simple_flying)
- AddComponent(/datum/component/swarming)
- AddComponent(/datum/component/clickbox, icon_state = clickbox_state, max_scale = clickbox_max_scale)
-
-/mob/living/simple_animal/hostile/asteroid/hivelordbrood/death(gibbed)
- if (!gibbed)
- new /obj/effect/temp_visual/hive_spawn_wither(get_turf(src), /* copy_from = */ src)
- return ..()
-
-//Legion
-/mob/living/simple_animal/hostile/asteroid/hivelord/legion
- name = "legion"
- desc = "You can still see what was once a human under the shifting mass of corruption."
- icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
- icon_state = "legion"
- icon_living = "legion"
- icon_aggro = "legion"
- icon_dead = "legion"
- icon_gib = "syndicate_gib"
- mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
- mouse_opacity = MOUSE_OPACITY_ICON
- obj_damage = 60
- melee_damage_lower = 15
- melee_damage_upper = 15
- attack_verb_continuous = "lashes out at"
- attack_verb_simple = "lash out at"
- speak_emote = list("echoes")
- attack_sound = 'sound/weapons/pierce.ogg'
- throw_message = "bounces harmlessly off of"
- crusher_loot = /obj/item/crusher_trophy/legion_skull
- loot = list(/obj/item/organ/internal/monster_core/regenerative_core/legion)
- brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion
- del_on_death = 1
- stat_attack = HARD_CRIT
- robust_searching = 1
- has_clickbox = FALSE
- var/dwarf_mob = FALSE
- var/snow_legion = FALSE
- var/mob/living/carbon/human/stored_mob
-
-/mob/living/simple_animal/hostile/asteroid/hivelord/legion/Initialize(mapload)
- . = ..()
- AddElement(/datum/element/content_barfer)
-
-/mob/living/simple_animal/hostile/asteroid/hivelord/legion/dwarf
- name = "dwarf legion"
- desc = "You can still see what was once a rather small human under the shifting mass of corruption."
- icon_state = "dwarf_legion"
- icon_living = "dwarf_legion"
- icon_aggro = "dwarf_legion"
- icon_dead = "dwarf_legion"
- maxHealth = 60
- health = 60
- speed = 2 //faster!
- crusher_drop_mod = 20
- dwarf_mob = TRUE
-
-/mob/living/simple_animal/hostile/asteroid/hivelord/legion/death(gibbed)
- visible_message(span_warning("The skulls on [src] wail in anger as they flee from their dying host!"))
- if (!isnull(stored_mob))
- stored_mob = null
- return ..()
-
- // We didn't contain a real body so spawn a random one
- var/turf/our_turf = get_turf(src)
- if(our_turf)
- if(from_spawner)
- new /obj/effect/mob_spawn/corpse/human/charredskeleton(our_turf)
- else if(dwarf_mob)
- new /obj/effect/mob_spawn/corpse/human/legioninfested/dwarf(our_turf)
- else if(snow_legion)
- new /obj/effect/mob_spawn/corpse/human/snowlegioninfested(our_turf)
- else
- new /obj/effect/mob_spawn/corpse/human/legioninfested(our_turf)
- return ..()
-
-/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril
- from_spawner = TRUE
-
-//Legion skull
-/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion
- name = "legion"
- desc = "One of many."
- icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
- icon_state = "legion_head"
- icon_living = "legion_head"
- icon_aggro = "legion_head"
- icon_dead = "legion_head"
- icon_gib = "syndicate_gib"
- friendly_verb_continuous = "buzzes near"
- friendly_verb_simple = "buzz near"
- vision_range = 10
- maxHealth = 1
- health = 5
- harm_intent_damage = 5
- melee_damage_lower = 12
- melee_damage_upper = 12
- attack_verb_continuous = "bites"
- attack_verb_simple = "bite"
- attack_vis_effect = ATTACK_EFFECT_BITE
- speak_emote = list("echoes")
- attack_sound = 'sound/weapons/pierce.ogg'
- throw_message = "is shrugged off by"
- del_on_death = TRUE
- stat_attack = HARD_CRIT
- robust_searching = 1
- clickbox_state = "sphere"
- clickbox_max_scale = 2
- var/can_infest_dead = FALSE
-
-/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/Life(seconds_per_tick = SSMOBS_DT, times_fired)
- . = ..()
- if(stat == DEAD || !isturf(loc))
- return
- for(var/mob/living/carbon/human/victim in range(src, 1)) //Only for corpse right next to/on same tile
- switch(victim.stat)
- if(UNCONSCIOUS, HARD_CRIT)
- infest(victim)
- return //This will qdelete the legion.
- if(DEAD)
- if(can_infest_dead)
- infest(victim)
- return //This will qdelete the legion.
-
-///Create a legion at the location of a corpse. Exists so that legion subtypes can override it with their own type of legion.
-/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/proc/make_legion(mob/living/carbon/human/H)
- if(HAS_TRAIT(H, TRAIT_DWARF)) //dwarf legions aren't just fluff!
- return new /mob/living/simple_animal/hostile/asteroid/hivelord/legion/dwarf(H.loc)
- else
- return new /mob/living/simple_animal/hostile/asteroid/hivelord/legion(H.loc)
-
-///Create a new legion using the supplied human H
-/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/proc/infest(mob/living/carbon/human/H)
- visible_message(span_warning("[name] burrows into the flesh of [H]!"))
- var/mob/living/simple_animal/hostile/asteroid/hivelord/legion/L = make_legion(H)
- visible_message(span_warning("[L] staggers to [L.p_their()] feet!"))
- H.investigate_log("has been killed by hivelord infestation.", INVESTIGATE_DEATHS)
- H.death()
- H.adjustBruteLoss(1000)
- L.stored_mob = H
- H.forceMove(L)
- qdel(src)
-
-//Advanced Legion is slightly tougher to kill and can raise corpses (revive other legions)
-/mob/living/simple_animal/hostile/asteroid/hivelord/legion/advanced
- stat_attack = DEAD
- maxHealth = 120
- health = 120
- brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/advanced
- icon_state = "dwarf_legion"
- icon_living = "dwarf_legion"
- icon_aggro = "dwarf_legion"
- icon_dead = "dwarf_legion"
-
-/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/advanced
- stat_attack = DEAD
- can_infest_dead = TRUE
-
-//Legion that spawns Legions
-/mob/living/simple_animal/hostile/big_legion
- name = "legion"
- desc = "One of many."
- icon = 'icons/mob/simple/lavaland/64x64megafauna.dmi'
- icon_state = "legion"
- icon_living = "legion"
- icon_dead = "legion"
- health_doll_icon = "legion"
- health = 450
- maxHealth = 450
- melee_damage_lower = 20
- melee_damage_upper = 20
- anchored = FALSE
- AIStatus = AI_ON
- stop_automated_movement = FALSE
- wander = TRUE
- maxbodytemp = INFINITY
- layer = MOB_LAYER
- del_on_death = TRUE
- sentience_type = SENTIENCE_BOSS
- loot = list(/obj/item/organ/internal/monster_core/regenerative_core/legion = 3, /obj/effect/mob_spawn/corpse/human/legioninfested = 5)
- move_to_delay = 14
- vision_range = 5
- aggro_vision_range = 9
- speed = 3
- faction = list(FACTION_MINING)
- weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE)
- obj_damage = 30
- environment_smash = ENVIRONMENT_SMASH_STRUCTURES
- // Purple, but bright cause we're gonna need to spot mobs on lavaland
- lighting_cutoff_red = 35
- lighting_cutoff_green = 20
- lighting_cutoff_blue = 45
-
-
-/mob/living/simple_animal/hostile/big_legion/Initialize(mapload)
- .=..()
- AddComponent(\
- /datum/component/spawner,\
- spawn_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion),\
- spawn_time = 20 SECONDS,\
- max_spawned = 3,\
- spawn_text = "peels itself off from",\
- faction = faction,\
- )
-
-
-// Snow Legion
-/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow
- name = "snow legion"
- desc = "You can still see what was once a human under the shifting snowy mass, clearly decorated by a clown."
- icon = 'icons/mob/simple/icemoon/icemoon_monsters.dmi'
- icon_state = "snowlegion"
- icon_living = "snowlegion"
- icon_aggro = "snowlegion_alive"
- icon_dead = "snowlegion"
- crusher_loot = /obj/item/crusher_trophy/legion_skull
- loot = list(/obj/item/organ/internal/monster_core/regenerative_core/legion)
- brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/snow
- weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE)
- snow_legion = TRUE
-
-/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/snow/make_legion(mob/living/carbon/human/H)
- return new /mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow(H.loc)
-
-/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/portal
- from_spawner = TRUE
-
-// Snow Legion skull
-/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/snow
- name = "snow legion"
- desc = "One of many."
- icon = 'icons/mob/simple/icemoon/icemoon_monsters.dmi'
- icon_state = "snowlegion_head"
- icon_living = "snowlegion_head"
- icon_aggro = "snowlegion_head"
- icon_dead = "snowlegion_head"
- weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE)
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/snake.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/snake.dm
deleted file mode 100644
index e128349bc2e..00000000000
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/snake.dm
+++ /dev/null
@@ -1,76 +0,0 @@
-
-/mob/living/simple_animal/hostile/retaliate/snake
- name = "snake"
- desc = "A slithery snake. These legless reptiles are the bane of mice and adventurers alike."
- icon_state = "snake"
- icon_living = "snake"
- icon_dead = "snake_dead"
- speak_emote = list("hisses")
- health = 20
- maxHealth = 20
- attack_verb_continuous = "bites"
- attack_verb_simple = "bite"
- attack_sound = 'sound/weapons/bite.ogg'
- attack_vis_effect = ATTACK_EFFECT_BITE
- melee_damage_lower = 5
- melee_damage_upper = 6
- response_help_continuous = "pets"
- response_help_simple = "pet"
- response_disarm_continuous = "shoos"
- response_disarm_simple = "shoo"
- response_harm_continuous = "steps on"
- response_harm_simple = "step on"
- faction = list(FACTION_HOSTILE)
- density = FALSE
- pass_flags = PASSTABLE | PASSMOB
- mob_size = MOB_SIZE_SMALL
- mob_biotypes = MOB_ORGANIC|MOB_BEAST|MOB_REPTILE
- gold_core_spawnable = FRIENDLY_SPAWN
- obj_damage = 0
- environment_smash = ENVIRONMENT_SMASH_NONE
-
-/mob/living/simple_animal/hostile/retaliate/snake/Initialize(mapload, special_reagent)
- . = ..()
- add_cell_sample()
- ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
- if(!special_reagent)
- special_reagent = /datum/reagent/toxin
- AddElement(/datum/element/venomous, special_reagent, 4)
-
-/mob/living/simple_animal/hostile/retaliate/snake/add_cell_sample()
- AddElement(/datum/element/swabable, CELL_LINE_TABLE_SNAKE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
-
-/mob/living/simple_animal/hostile/retaliate/snake/ListTargets(atom/the_target)
- var/atom/target_from = GET_TARGETS_FROM(src)
- . = oview(vision_range, target_from) //get list of things in vision range
- var/list/living_mobs = list()
- var/list/mice = list()
- for (var/HM in .)
- //Yum a tasty mouse
- if(ismouse(HM))
- mice += HM
- if(isliving(HM))
- living_mobs += HM
-
- // if no tasty mice to chase, lets chase any living mob enemies in our vision range
- if(length(mice))
- return mice
-
- var/list/actual_enemies = list()
- for(var/datum/weakref/enemy as anything in enemies)
- var/mob/flesh_and_blood = enemy.resolve()
- if(!flesh_and_blood)
- enemies -= enemy
- continue
- actual_enemies += flesh_and_blood
-
- //Filter living mobs (in range mobs) by those we consider enemies (retaliate behaviour)
- return living_mobs & actual_enemies
-
-/mob/living/simple_animal/hostile/retaliate/snake/AttackingTarget()
- if(ismouse(target))
- visible_message(span_notice("[name] consumes [target] in a single gulp!"), span_notice("You consume [target] in a single gulp!"))
- QDEL_NULL(target)
- adjustBruteLoss(-2)
- else
- return ..()
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index 74a27e2a014..4966ac76a8e 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -315,7 +315,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
if(parrot_state == PARROT_PERCH)
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
- parrot_interest = user
+ set_parrot_interest(user)
parrot_state = PARROT_SWOOP //The parrot just got hit, it WILL move, now to pick a direction..
if(health > 30) //Let's get in there and squawk it up!
@@ -344,7 +344,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
if(user.melee_damage_upper > 0 && !stat)
- parrot_interest = user
+ set_parrot_interest(user)
parrot_state = PARROT_SWOOP | PARROT_ATTACK //Attack other animals regardless
icon_state = icon_living
@@ -355,7 +355,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
if(parrot_state == PARROT_PERCH)
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
- parrot_interest = user
+ set_parrot_interest(user)
parrot_state = PARROT_SWOOP
if(health > 30) //Let's get in there and squawk it up!
parrot_state |= PARROT_ATTACK
@@ -380,7 +380,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
if(parrot_state == PARROT_PERCH)
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
- parrot_interest = null
+ set_parrot_interest(null)
parrot_state = PARROT_WANDER | PARROT_FLEE //Been shot and survived! RUN LIKE HELL!
//parrot_been_shot += 5
icon_state = icon_living
@@ -475,7 +475,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
speak = newspeak
//Search for item to steal
- parrot_interest = search_for_item()
+ set_parrot_interest(search_for_item())
if(parrot_interest)
manual_emote("looks in [parrot_interest]'s direction and takes flight.")
parrot_state = PARROT_SWOOP | PARROT_STEAL
@@ -486,7 +486,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
else if(parrot_state == PARROT_WANDER)
//Stop movement, we'll set it later
SSmove_manager.stop_looping(src)
- parrot_interest = null
+ set_parrot_interest(null)
//Wander around aimlessly. This will help keep the loops from searches down
//and possibly move the mob into a new are in view of something they can use
@@ -498,7 +498,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
var/atom/movable/AM = search_for_perch_and_item() //This handles checking through lists so we know it's either a perch or stealable item
if(AM)
if(isitem(AM) || isliving(AM)) //If stealable item
- parrot_interest = AM
+ set_parrot_interest(AM)
manual_emote("turns and flies towards [parrot_interest].")
parrot_state = PARROT_SWOOP | PARROT_STEAL
return
@@ -543,7 +543,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
parrot_interest.forceMove(src)
visible_message(span_notice("[src] grabs [held_item]!"), span_notice("You grab [held_item]!"), span_hear("You hear the sounds of wings flapping furiously."))
- parrot_interest = null
+ set_parrot_interest(null)
parrot_state = PARROT_SWOOP | PARROT_RETURN
return
@@ -591,7 +591,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
//If we're attacking a nothing, an object, a turf or a ghost for some stupid reason, switch to wander
if(!parrot_interest || !isliving(parrot_interest))
- parrot_interest = null
+ set_parrot_interest(null)
parrot_state = PARROT_WANDER
return
@@ -605,7 +605,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
//If the mob we've been chasing/attacking dies or falls into crit, check for loot!
if(L.stat)
- parrot_interest = null
+ set_parrot_interest(null)
if(!held_item)
held_item = steal_from_ground()
if(!held_item)
@@ -629,7 +629,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
//-----STATE MISHAP
else //This should not happen. If it does lets reset everything and try again
SSmove_manager.stop_looping(src)
- parrot_interest = null
+ set_parrot_interest(null)
parrot_perch = null
drop_held_item()
parrot_state = PARROT_WANDER
@@ -639,6 +639,17 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
* Procs
*/
+/mob/living/simple_animal/parrot/proc/set_parrot_interest(atom/movable/shiny)
+ if(parrot_interest)
+ UnregisterSignal(parrot_interest, COMSIG_QDELETING)
+ parrot_interest = shiny
+ if(parrot_interest)
+ RegisterSignal(parrot_interest, COMSIG_QDELETING, PROC_REF(shiny_deleted))
+
+/mob/living/simple_animal/parrot/proc/shiny_deleted(datum/source)
+ SIGNAL_HANDLER
+ set_parrot_interest(null)
+
/mob/living/simple_animal/parrot/proc/isStuck()
//Check to see if the parrot is stuck due to things like windows or doors or windowdoors
if(parrot_lastmove)
@@ -1038,7 +1049,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
/mob/living/simple_animal/parrot/poly/ghost/handle_automated_movement()
if(isliving(parrot_interest))
if(!ishuman(parrot_interest))
- parrot_interest = null
+ set_parrot_interest(null)
else if(parrot_state == (PARROT_SWOOP | PARROT_ATTACK) && Adjacent(parrot_interest))
SSmove_manager.move_to(src, parrot_interest, 0, parrot_speed)
Possess(parrot_interest)
@@ -1051,7 +1062,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
P.parrot = src
forceMove(H)
H.ForceContractDisease(P, FALSE)
- parrot_interest = null
+ set_parrot_interest(null)
H.visible_message(span_danger("[src] dive bombs into [H]'s chest and vanishes!"), span_userdanger("[src] dive bombs into your chest, vanishing! This can't be good!"))
#undef PARROT_PERCH
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 2fdec746899..cebb747f6ba 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1405,8 +1405,11 @@
. = ..()
VV_DROPDOWN_OPTION("", "---------")
VV_DROPDOWN_OPTION(VV_HK_GIB, "Gib")
+ VV_DROPDOWN_OPTION(VV_HK_REMOVE_SPELL, "Remove Spell")
VV_DROPDOWN_OPTION(VV_HK_GIVE_SPELL, "Give Spell")
VV_DROPDOWN_OPTION(VV_HK_REMOVE_SPELL, "Remove Spell")
+ VV_DROPDOWN_OPTION(VV_HK_GIVE_MOB_ACTION, "Give Mob Ability")
+ VV_DROPDOWN_OPTION(VV_HK_REMOVE_MOB_ACTION, "Remove Mob Ability")
VV_DROPDOWN_OPTION(VV_HK_GIVE_DISEASE, "Give Disease")
VV_DROPDOWN_OPTION(VV_HK_GODMODE, "Toggle Godmode")
VV_DROPDOWN_OPTION(VV_HK_DROP_ALL, "Drop Everything")
@@ -1433,6 +1436,14 @@
if(!check_rights(R_ADMIN))
return
usr.client.cmd_admin_godmode(src)
+ if(href_list[VV_HK_GIVE_MOB_ACTION])
+ if(!check_rights(NONE))
+ return
+ usr.client.give_mob_action(src)
+ if(href_list[VV_HK_REMOVE_MOB_ACTION])
+ if(!check_rights(NONE))
+ return
+ usr.client.remove_mob_action(src)
if(href_list[VV_HK_GIVE_SPELL])
if(!check_rights(NONE))
return
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 3e561c75341..7df256d1873 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -207,20 +207,38 @@
return ""
// moved out of admins.dm because things other than admin procs were calling this.
-/// Returns TRUE if the game has started and we're either an AI with a 0th law, or we're someone with a special role/antag datum
-/proc/is_special_character(mob/M)
+/**
+ * Returns TRUE if the game has started and we're either an AI with a 0th law, or we're someone with a special role/antag datum
+ * If allow_fake_antags is set to FALSE, Valentines, ERTs, and any such roles with FLAG_FAKE_ANTAG won't pass.
+*/
+/proc/is_special_character(mob/M, allow_fake_antags = FALSE)
if(!SSticker.HasRoundStarted())
return FALSE
if(!istype(M))
return FALSE
if(iscyborg(M)) //as a borg you're now beholden to your laws rather than greentext
return FALSE
+
+
+ // Returns TRUE if AI has a zeroth law *and* either has a special role *or* an antag datum.
if(isAI(M))
var/mob/living/silicon/ai/A = M
return (A.laws?.zeroth && (A.mind?.special_role || !isnull(M.mind?.antag_datums)))
- if(M.mind?.special_role || !isnull(M.mind?.antag_datums)) //they have an antag datum!
+
+ if(M.mind?.special_role)
return TRUE
- return FALSE
+
+ // Turns 'faker' to TRUE if the antag datum is fake. If it's not fake, returns TRUE directly.
+ var/faker = FALSE
+ for(var/datum/antagonist/antag_datum as anything in M.mind?.antag_datums)
+ if((antag_datum.antag_flags & FLAG_FAKE_ANTAG))
+ faker = TRUE
+ else
+ return TRUE
+
+ // If 'faker' was assigned TRUE in the above loop and the argument 'allow_fake_antags' is set to TRUE, this passes.
+ // Else, return FALSE.
+ return (faker && allow_fake_antags)
/**
* Fancy notifications for ghosts
@@ -521,3 +539,33 @@
"[key_name(src)] manually changed selected zone",
data,
)
+
+/**
+ * Returns an associative list of the logs of a certain amount of lines spoken recently by this mob
+ * copy_amount - number of lines to return
+ * line_chance - chance to return a line, if you don't want just the most recent x lines
+ */
+/mob/proc/copy_recent_speech(copy_amount = LING_ABSORB_RECENT_SPEECH, line_chance = 100)
+ var/list/recent_speech = list()
+ var/list/say_log = list()
+ var/log_source = logging
+ for(var/log_type in log_source)
+ var/nlog_type = text2num(log_type)
+ if(nlog_type & LOG_SAY)
+ var/list/reversed = log_source[log_type]
+ if(islist(reversed))
+ say_log = reverse_range(reversed.Copy())
+ break
+
+ for(var/spoken_memory in say_log)
+ if(recent_speech.len >= copy_amount)
+ break
+ if(!prob(line_chance))
+ continue
+ recent_speech[spoken_memory] = splittext(say_log[spoken_memory], "\"", 1, 0, TRUE)[3]
+
+ var/list/raw_lines = list()
+ for (var/key as anything in recent_speech)
+ raw_lines += recent_speech[key]
+
+ return raw_lines
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index e9b0f532da5..03712663249 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -132,7 +132,7 @@
//Basically an optional override for our glide size
//Sometimes you want to look like you're moving with a delay you don't actually have yet
visual_delay = 0
- var/old_dir = dir
+ var/old_dir = mob.dir
. = ..()
diff --git a/code/modules/mob_spawn/corpses/mining_corpses.dm b/code/modules/mob_spawn/corpses/mining_corpses.dm
index c0ea4b6af42..8b7ad474b16 100644
--- a/code/modules/mob_spawn/corpses/mining_corpses.dm
+++ b/code/modules/mob_spawn/corpses/mining_corpses.dm
@@ -16,18 +16,21 @@
//Legion infested mobs
-//dwarf type which spawns dwarfy versions
-/obj/effect/mob_spawn/corpse/human/legioninfested/dwarf
-
-/obj/effect/mob_spawn/corpse/human/legioninfested/dwarf/special(mob/living/carbon/human/spawned_human)
- . = ..()
- spawned_human.dna.add_mutation(/datum/mutation/human/dwarfism)
-
-//main type, rolls a pool of legion victims
+/// Mob spawner used by Legion to spawn costumed bodies
/obj/effect/mob_spawn/corpse/human/legioninfested
brute_damage = 1000
/obj/effect/mob_spawn/corpse/human/legioninfested/Initialize(mapload)
+ outfit = select_outfit()
+ return ..()
+
+/obj/effect/mob_spawn/corpse/human/legioninfested/special(mob/living/carbon/human/spawned_human)
+ . = ..()
+ var/obj/item/organ/internal/legion_tumour/cancer = new()
+ cancer.Insert(spawned_human, special = TRUE, drop_if_replaced = FALSE)
+
+/// Returns the outfit worn by our corpse
+/obj/effect/mob_spawn/corpse/human/legioninfested/proc/select_outfit()
var/corpse_theme = pick_weight(list(
"Miner" = 64,
"Clown" = 5,
@@ -40,26 +43,36 @@
"Shadow",
)) = 4,
))
+
switch(corpse_theme)
if("Miner")
- outfit = /datum/outfit/consumed_miner
+ return /datum/outfit/consumed_miner
if("Ashwalker")
- outfit = /datum/outfit/consumed_ashwalker
+ return /datum/outfit/consumed_ashwalker
if("Golem")
- outfit = /datum/outfit/consumed_golem
+ return /datum/outfit/consumed_golem
if("Clown")
- outfit = /datum/outfit/consumed_clown
+ return /datum/outfit/consumed_clown
if("Cultist")
- outfit = /datum/outfit/consumed_cultist
+ return /datum/outfit/consumed_cultist
if("Dame")
- outfit = /datum/outfit/consumed_dame
+ return /datum/outfit/consumed_dame
if("Operative")
- outfit = /datum/outfit/syndicatecommandocorpse/lessenedgear
+ return /datum/outfit/syndicatecommandocorpse/lessenedgear
if("Shadow")
- outfit = /datum/outfit/consumed_shadowperson
+ return /datum/outfit/consumed_shadowperson
+
+/// Corpse spawner used by dwarf legions to make small corpses
+/obj/effect/mob_spawn/corpse/human/legioninfested/dwarf
+
+/obj/effect/mob_spawn/corpse/human/legioninfested/dwarf/special(mob/living/carbon/human/spawned_human)
. = ..()
+ spawned_human.dna.add_mutation(/datum/mutation/human/dwarfism)
+
+/// Corpse spawner used by snow legions with alternate costumes
+/obj/effect/mob_spawn/corpse/human/legioninfested/snow
-/obj/effect/mob_spawn/corpse/human/snowlegioninfested/Initialize(mapload)
+/obj/effect/mob_spawn/corpse/human/legioninfested/snow/select_outfit()
var/corpse_theme = pick_weight(list(
"Miner" = 64,
"Clown" = 5,
@@ -72,24 +85,49 @@
"Shadow",
)) = 4,
))
+
switch(corpse_theme)
if("Miner")
- outfit = /datum/outfit/consumed_miner
+ return /datum/outfit/consumed_miner
if("Settler")
- outfit = /datum/outfit/consumed_ice_settler
+ return /datum/outfit/consumed_ice_settler
if("Heremoth")
- outfit = /datum/outfit/consumed_heremoth
+ return /datum/outfit/consumed_heremoth
if("Clown")
- outfit = /datum/outfit/consumed_clown
+ return /datum/outfit/consumed_clown
if("Cultist")
- outfit = /datum/outfit/consumed_cultist
+ return /datum/outfit/consumed_cultist
if("Golem")
- outfit = /datum/outfit/consumed_golem
+ return /datum/outfit/consumed_golem
if("Operative")
- outfit = /datum/outfit/syndicatecommandocorpse/lessenedgear
+ return /datum/outfit/syndicatecommandocorpse/lessenedgear
if("Shadow")
- outfit = /datum/outfit/consumed_shadowperson
+ return /datum/outfit/consumed_shadowperson
+
+/// Creates a dead legion-infested skeleton
+/obj/effect/mob_spawn/corpse/human/legioninfested/skeleton
+ name = "legion-infested skeleton"
+ mob_name = "skeleton"
+ mob_species = /datum/species/skeleton
+
+/obj/effect/mob_spawn/corpse/human/legioninfested/skeleton/select_outfit()
+ return null
+
+/obj/effect/mob_spawn/corpse/human/legioninfested/skeleton/special(mob/living/carbon/human/spawned_human)
. = ..()
+ spawned_human.gender = NEUTER
+
+/// Creates a dead and burned legion-infested skeleton
+/obj/effect/mob_spawn/corpse/human/legioninfested/skeleton/charred
+ name = "charred legion-infested skeleton"
+ mob_name = "charred skeleton"
+ brute_damage = 0
+ burn_damage = 1000
+
+/obj/effect/mob_spawn/corpse/human/legioninfested/skeleton/charred/special(mob/living/carbon/human/spawned_human)
+ . = ..()
+ spawned_human.color = "#454545"
+
/datum/outfit/consumed_miner
name = "Legion-Consumed Miner"
diff --git a/code/modules/mob_spawn/ghost_roles/drone_roles.dm b/code/modules/mob_spawn/ghost_roles/drone_roles.dm
new file mode 100644
index 00000000000..b8a31a16b13
--- /dev/null
+++ b/code/modules/mob_spawn/ghost_roles/drone_roles.dm
@@ -0,0 +1,6 @@
+/obj/effect/mob_spawn/ghost_role/drone/name_mob(mob/living/spawned_mob, forced_name)
+ if(!forced_name)
+ var/designation = pick(GLOB.posibrain_names)
+ forced_name = "Drone ([designation]-[rand(100, 999)])"
+
+ return ..()
diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm
index f11c6b9b4b9..f8daa9bab54 100644
--- a/code/modules/mod/mod_types.dm
+++ b/code/modules/mod/mod_types.dm
@@ -260,6 +260,12 @@
/obj/item/mod/module/jump_jet,
)
+/obj/item/mod/control/pre_equipped/nuclear/no_jetpack
+
+/obj/item/mod/control/pre_equipped/nuclear/no_jetpack/Initialize(mapload, new_theme, new_skin, new_core)
+ applied_modules -= list(/obj/item/mod/module/jetpack/advanced, /obj/item/mod/module/jump_jet)
+ return ..()
+
/obj/item/mod/control/pre_equipped/nuclear/plasmaman
/obj/item/mod/control/pre_equipped/nuclear/plasmaman/Initialize(mapload, new_theme, new_skin, new_core)
diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm
index 21d2b8352fb..6fe91c9575b 100644
--- a/code/modules/modular_computers/computers/item/computer.dm
+++ b/code/modules/modular_computers/computers/item/computer.dm
@@ -150,6 +150,7 @@
close_all_programs()
//Some components will actually try and interact with this, so let's do it later
QDEL_NULL(soundloop)
+ looping_sound = FALSE // Necessary to stop a possible runtime trying to call soundloop.stop() when soundloop has been qdel'd
QDEL_LIST(stored_files)
if(istype(inserted_disk))
@@ -802,14 +803,8 @@
/obj/item/modular_computer/wrench_act_secondary(mob/living/user, obj/item/tool)
. = ..()
tool.play_tool_sound(src, user, 20, volume=20)
- internal_cell?.forceMove(drop_location())
- computer_id_slot?.forceMove(drop_location())
- inserted_disk?.forceMove(drop_location())
- remove_pai()
- new /obj/item/stack/sheet/iron(get_turf(loc), steel_sheet_cost)
+ deconstruct(TRUE)
user.balloon_alert(user, "disassembled")
- relay_qdel()
- qdel(src)
return TOOL_ACT_TOOLTYPE_SUCCESS
/obj/item/modular_computer/welder_act(mob/living/user, obj/item/tool)
@@ -830,15 +825,26 @@
return TOOL_ACT_TOOLTYPE_SUCCESS
/obj/item/modular_computer/deconstruct(disassembled = TRUE)
- break_apart()
- return ..()
-
-/obj/item/modular_computer/proc/break_apart()
+ remove_pai()
+ eject_aicard()
if(!(flags_1 & NODECONSTRUCT_1))
- physical.visible_message(span_notice("\The [src] breaks apart!"))
- var/turf/newloc = get_turf(src)
- new /obj/item/stack/sheet/iron(newloc, round(steel_sheet_cost / 2))
+ if (disassembled)
+ internal_cell?.forceMove(drop_location())
+ computer_id_slot?.forceMove(drop_location())
+ inserted_disk?.forceMove(drop_location())
+ new /obj/item/stack/sheet/iron(drop_location(), steel_sheet_cost)
+ else
+ physical.visible_message(span_notice("\The [src] breaks apart!"))
+ new /obj/item/stack/sheet/iron(drop_location(), round(steel_sheet_cost * 0.5))
relay_qdel()
+ return ..()
+
+// Ejects the inserted intellicard, if one exists. Used when the computer is deconstructed.
+/obj/item/modular_computer/proc/eject_aicard()
+ var/datum/computer_file/program/ai_restorer/program = locate() in stored_files
+ if (program)
+ return program.try_eject(forced = TRUE)
+ return FALSE
// Used by processor to relay qdel() to machinery type.
/obj/item/modular_computer/proc/relay_qdel()
diff --git a/code/modules/modular_computers/computers/machinery/modular_computer.dm b/code/modules/modular_computers/computers/machinery/modular_computer.dm
index 33f4bc29a16..293cdd9c5f7 100644
--- a/code/modules/modular_computers/computers/machinery/modular_computer.dm
+++ b/code/modules/modular_computers/computers/machinery/modular_computer.dm
@@ -125,9 +125,9 @@
return cpu.screwdriver_act(user, tool)
return ..()
-/obj/machinery/modular_computer/wrench_act(mob/user, obj/item/tool)
+/obj/machinery/modular_computer/wrench_act_secondary(mob/user, obj/item/tool)
if(cpu)
- return cpu.wrench_act(user, tool)
+ return cpu.wrench_act_secondary(user, tool)
return ..()
/obj/machinery/modular_computer/welder_act(mob/user, obj/item/tool)
diff --git a/code/modules/modular_computers/file_system/programs/records.dm b/code/modules/modular_computers/file_system/programs/records.dm
index 960702d608c..9b5617364c0 100644
--- a/code/modules/modular_computers/file_system/programs/records.dm
+++ b/code/modules/modular_computers/file_system/programs/records.dm
@@ -45,6 +45,7 @@
current_record["rank"] = person.rank
current_record["species"] = person.species
current_record["wanted"] = person.wanted_status
+ current_record["voice"] = person.voice
all_records += list(current_record)
if("medical")
diff --git a/code/modules/movespeed/modifiers/mobs.dm b/code/modules/movespeed/modifiers/mobs.dm
index 59b514a3d57..e5f29323223 100644
--- a/code/modules/movespeed/modifiers/mobs.dm
+++ b/code/modules/movespeed/modifiers/mobs.dm
@@ -84,9 +84,6 @@
/datum/movespeed_modifier/shove
multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH
-/datum/movespeed_modifier/borg_throw
- multiplicative_slowdown = 0.9
-
/datum/movespeed_modifier/human_carry
multiplicative_slowdown = HUMAN_CARRY_SLOWDOWN
blacklisted_movetypes = FLOATING
diff --git a/code/modules/pai/pai.dm b/code/modules/pai/pai.dm
index 8c3039d8c62..e1a4dfb0ae0 100644
--- a/code/modules/pai/pai.dm
+++ b/code/modules/pai/pai.dm
@@ -111,6 +111,7 @@
"crow" = TRUE,
"duffel" = TRUE,
"fox" = FALSE,
+ "frog" = TRUE,
"hawk" = FALSE,
"lizard" = FALSE,
"monkey" = TRUE,
diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm
index cb6aae768fa..ed99e7ea179 100644
--- a/code/modules/paperwork/filingcabinet.dm
+++ b/code/modules/paperwork/filingcabinet.dm
@@ -193,9 +193,9 @@ GLOBAL_LIST_EMPTY(employmentCabinets)
/obj/structure/filingcabinet/employment/proc/fillCurrent()
//This proc fills the cabinet with the current crew.
for(var/datum/record/locked/target in GLOB.manifest.locked)
- var/datum/mind/mind_ref = target.mind_ref
- if(mind_ref && ishuman(mind_ref.current))
- addFile(mind_ref.current)
+ var/datum/mind/filed_mind = target.mind_ref.resolve()
+ if(filed_mind && ishuman(filed_mind.current))
+ addFile(filed_mind.current)
/obj/structure/filingcabinet/employment/proc/addFile(mob/living/carbon/human/employee)
new /obj/item/paper/employment_contract(src, employee.mind.name)
diff --git a/code/modules/photography/_pictures.dm b/code/modules/photography/_pictures.dm
index 8c949892dbf..45fa5654ad9 100644
--- a/code/modules/photography/_pictures.dm
+++ b/code/modules/photography/_pictures.dm
@@ -5,6 +5,8 @@
var/list/mobs_seen = list()
/// List of weakrefs pointing at dead mobs that appear in this photo
var/list/dead_seen = list()
+ /// List of strings of face-visible humans in this photo
+ var/list/names_seen = list()
var/caption
var/icon/picture_image
var/icon/picture_icon
@@ -16,7 +18,7 @@
///Was this image capable of seeing ghosts?
var/see_ghosts = CAMERA_NO_GHOSTS
-/datum/picture/New(name, desc, mobs_spotted, dead_spotted, image, icon, size_x, size_y, bp, caption_, autogenerate_icon, can_see_ghosts)
+/datum/picture/New(name, desc, mobs_spotted, dead_spotted, names, image, icon, size_x, size_y, bp, caption_, autogenerate_icon, can_see_ghosts)
if(!isnull(name))
picture_name = name
if(!isnull(desc))
@@ -27,6 +29,9 @@
if(!isnull(dead_spotted))
for(var/mob/seen as anything in dead_spotted)
dead_seen += WEAKREF(seen)
+ if(!isnull(names))
+ for(var/seen in names)
+ names_seen += seen
if(!isnull(image))
picture_image = image
if(!isnull(icon))
diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm
index 1c0e360ed75..b168aaf54da 100644
--- a/code/modules/photography/camera/camera.dm
+++ b/code/modules/photography/camera/camera.dm
@@ -188,6 +188,8 @@
var/list/mobs = list()
var/blueprints = FALSE
var/clone_area = SSmapping.request_turf_block_reservation(size_x * 2 + 1, size_y * 2 + 1, 1)
+ ///list of human names taken on picture
+ var/list/names = list()
var/width = size_x * 2 + 1
var/height = size_y * 2 + 1
@@ -218,8 +220,11 @@
var/icon/get_icon = camera_get_icon(turfs, target_turf, psize_x, psize_y, clone_area, size_x, size_y, (size_x * 2 + 1), (size_y * 2 + 1))
qdel(clone_area)
get_icon.Blend("#000", ICON_UNDERLAY)
+ for(var/mob/living/carbon/human/person in mobs)
+ if(person.is_face_visible())
+ names += "[person.name]"
- var/datum/picture/picture = new("picture", desc.Join(" "), mobs_spotted, dead_spotted, get_icon, null, psize_x, psize_y, blueprints, can_see_ghosts = see_ghosts)
+ var/datum/picture/picture = new("picture", desc.Join(" "), mobs_spotted, dead_spotted, names, get_icon, null, psize_x, psize_y, blueprints, can_see_ghosts = see_ghosts)
after_picture(user, picture)
SEND_SIGNAL(src, COMSIG_CAMERA_IMAGE_CAPTURED, target, user)
blending = FALSE
diff --git a/code/modules/photography/photos/photo.dm b/code/modules/photography/photos/photo.dm
index 9be79a58266..b34ff459c00 100644
--- a/code/modules/photography/photos/photo.dm
+++ b/code/modules/photography/photos/photo.dm
@@ -54,11 +54,11 @@
icon = I
return ..()
-/obj/item/photo/suicide_act(mob/living/carbon/user)
+/obj/item/photo/suicide_act(mob/living/carbon/human/user)
user.visible_message(span_suicide("[user] is taking one last look at \the [src]! It looks like [user.p_theyre()] giving in to death!"))//when you wanna look at photo of waifu one last time before you die...
- if (user.gender == MALE)
+ if (!ishuman(user) || user.physique == MALE)
playsound(user, 'sound/voice/human/manlaugh1.ogg', 50, TRUE)//EVERY TIME I DO IT MAKES ME LAUGH
- else if (user.gender == FEMALE)
+ else
playsound(user, 'sound/voice/human/womanlaugh.ogg', 50, TRUE)
return OXYLOSS
diff --git a/code/modules/power/rtg.dm b/code/modules/power/rtg.dm
index c49bc455165..974c2e66737 100644
--- a/code/modules/power/rtg.dm
+++ b/code/modules/power/rtg.dm
@@ -71,7 +71,7 @@
visible_message(span_danger("\The [src] lets out a shower of sparks as it starts to lose stability!"),\
span_hear("You hear a loud electrical crack!"))
playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5)
- tesla_zap(src, 5, power_gen * 0.05)
+ tesla_zap(src, 5, power_gen * 20)
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(explosion), src, 2, 3, 4, null, 8), 10 SECONDS) // Not a normal explosion.
/obj/machinery/power/rtg/abductor/bullet_act(obj/projectile/Proj)
diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm
index 654ea805440..8598b3cccf2 100644
--- a/code/modules/power/supermatter/supermatter.dm
+++ b/code/modules/power/supermatter/supermatter.dm
@@ -53,8 +53,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
var/damage_archived = 0
var/list/damage_factors
- /// How much extra power does the main zap generate.
- var/zap_multiplier = 1
+ /// The zap power transmission over internal energy. W/MeV.
+ var/zap_transmission_rate = BASE_POWER_TRANSMISSION_RATE
var/list/zap_factors
/// The temperature at which we start taking damage
@@ -95,7 +95,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
/// How much power decay is negated. Complete power decay negation at 1.
var/gas_powerloss_inhibition = 0
/// Affects the amount of power the main SM zap makes.
- var/gas_power_transmission = 0
+ var/gas_power_transmission_rate = 0
/// Affects the power gain the SM experiances from heat.
var/gas_heat_power_generation = 0
@@ -109,7 +109,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
var/external_damage_immediate = 0
///The cutoff for a bolt jumping, grows with heat, lowers with higher mol count,
- var/zap_cutoff = 1500
+ var/zap_cutoff = 1.2e6
///How much the bullets damage should be multiplied by when it is added to the internal variables
var/bullet_energy = SUPERMATTER_DEFAULT_BULLET_ENERGY
///How much hallucination should we produce per unit of power?
@@ -153,6 +153,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
///Stores the time of when the last zap occurred
var/last_power_zap = 0
+ var/last_high_energy_zap = 0
///Do we show this crystal in the CIMS modular program
var/include_in_cims = TRUE
@@ -275,7 +276,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
// PART 3: POWER PROCESSING
internal_energy_factors = calculate_internal_energy()
- zap_factors = calculate_zap_multiplier()
+ zap_factors = calculate_zap_transmission_rate()
if(internal_energy && (last_power_zap + (4 - internal_energy * 0.001) SECONDS) < world.time)
playsound(src, 'sound/weapons/emitter2.ogg', 70, TRUE)
hue_angle_shift = clamp(903 * log(10, (internal_energy + 8000)) - 3590, -50, 240)
@@ -286,9 +287,9 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
supermatter_zap(
zapstart = src,
range = 3,
- zap_str = 1.25 * internal_energy * zap_multiplier * delta_time,
+ zap_str = internal_energy * zap_transmission_rate * delta_time,
zap_flags = ZAP_SUPERMATTER_FLAGS,
- zap_cutoff = 300 * delta_time,
+ zap_cutoff = 2.4e5 * delta_time,
power_level = internal_energy,
color = zap_color,
)
@@ -374,15 +375,20 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
"name" = factor,
"amount" = amount * -1
))
+ var/list/internal_energy_si_derived_data = siunit_isolated(internal_energy * 1e6, "eV", 3)
data["internal_energy"] = internal_energy
+ data["internal_energy_coefficient"] = internal_energy_si_derived_data[SI_COEFFICIENT]
+ data["internal_energy_unit"] = internal_energy_si_derived_data[SI_UNIT]
data["internal_energy_factors"] = list()
for (var/factor in internal_energy_factors)
+ var/list/internal_energy_factor_si_derived_data = siunit_isolated(internal_energy_factors[factor] * 1e6, "eV", 3)
var/amount = round(internal_energy_factors[factor], 0.01)
if(!amount)
continue
data["internal_energy_factors"] += list(list(
"name" = factor,
- "amount" = amount
+ "amount" = internal_energy_factor_si_derived_data[SI_COEFFICIENT],
+ "unit" = internal_energy_factor_si_derived_data[SI_UNIT],
))
data["temp_limit"] = temp_limit
data["temp_limit_factors"] = list()
@@ -392,7 +398,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
continue
data["temp_limit_factors"] += list(list(
"name" = factor,
- "amount" = amount
+ "amount" = amount,
))
data["waste_multiplier"] = waste_multiplier
data["waste_multiplier_factors"] = list()
@@ -402,18 +408,42 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
continue
data["waste_multiplier_factors"] += list(list(
"name" = factor,
- "amount" = amount
+ "amount" = amount,
))
- data["zap_multiplier"] = zap_multiplier
- data["zap_multiplier_factors"] = list()
+
+ data["zap_transmission_factors"] = list()
for (var/factor in zap_factors)
- var/amount = round(zap_factors[factor], 0.01)
- if(!amount)
+ var/list/zap_factor_si_derived_data = siunit_isolated(zap_factors[factor] * internal_energy, "W", 2)
+ if(!zap_factor_si_derived_data[SI_COEFFICIENT])
continue
- data["zap_multiplier_factors"] += list(list(
+ data["zap_transmission_factors"] += list(list(
"name" = factor,
- "amount" = amount
+ "amount" = zap_factor_si_derived_data[SI_COEFFICIENT],
+ "unit" = zap_factor_si_derived_data[SI_UNIT],
))
+
+ ///Add high energy bonus to the zap transmission data so we can accurately measure our power generation from zaps.
+ var/high_energy_bonus = 0
+ var/zap_transmission = zap_transmission_rate * internal_energy
+ var/zap_power_multiplier = 1
+ if(internal_energy > POWER_PENALTY_THRESHOLD) //Supermatter zaps multiply power internally under some conditions for some reason, so we'll snowflake this for now.
+ ///Power multiplier bonus applied to all zaps. Zap power generation doubles when it reaches 7GeV and 9GeV.
+ zap_power_multiplier *= 2 ** clamp(round((internal_energy - POWER_PENALTY_THRESHOLD) / 2000), 0, 2)
+ ///The supermatter releases additional zaps after 5GeV, with more at 7GeV and 9GeV.
+ var/additional_zap_bonus = clamp(internal_energy * 3200, 6.4e6, 3.2e7) * clamp(round(INVERSE_LERP(1000, 3000, internal_energy)), 1, 4)
+ high_energy_bonus = (zap_transmission + additional_zap_bonus) * zap_power_multiplier - zap_transmission
+ var/list/zap_factor_si_derived_data = siunit_isolated(high_energy_bonus, "W", 2)
+ data["zap_transmission_factors"] += list(list(
+ "name" = "High Energy Bonus",
+ "amount" = zap_factor_si_derived_data[SI_COEFFICIENT],
+ "unit" = zap_factor_si_derived_data[SI_UNIT],
+ ))
+
+ var/list/zap_transmission_si_derived_data = siunit_isolated(zap_transmission + high_energy_bonus, "W", 2)
+ data["zap_transmission"] = zap_transmission + high_energy_bonus
+ data["zap_transmission_coefficient"] = zap_transmission_si_derived_data[SI_COEFFICIENT]
+ data["zap_transmission_unit"] = zap_transmission_si_derived_data[SI_UNIT]
+
data["absorbed_ratio"] = absorption_ratio
var/list/formatted_gas_percentage = list()
for (var/datum/gas/gas_path as anything in subtypesof(/datum/gas))
@@ -577,7 +607,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
*
* Updates:
* [/obj/machinery/power/supermatter_crystal/var/list/gas_percentage]
- * [/obj/machinery/power/supermatter_crystal/var/gas_power_transmission]
+ * [/obj/machinery/power/supermatter_crystal/var/gas_power_transmission_rate]
* [/obj/machinery/power/supermatter_crystal/var/gas_heat_modifier]
* [/obj/machinery/power/supermatter_crystal/var/gas_heat_resistance]
* [/obj/machinery/power/supermatter_crystal/var/gas_heat_power_generation]
@@ -590,7 +620,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
return
gas_percentage = list()
- gas_power_transmission = 0
+ gas_power_transmission_rate = 0
gas_heat_modifier = 0
gas_heat_resistance = 0
gas_heat_power_generation = 0
@@ -607,7 +637,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
var/datum/sm_gas/sm_gas = current_gas_behavior[gas_path]
if(!sm_gas)
continue
- gas_power_transmission += sm_gas.power_transmission * gas_percentage[gas_path]
+ gas_power_transmission_rate += sm_gas.power_transmission * gas_percentage[gas_path]
gas_heat_modifier += sm_gas.heat_modifier * gas_percentage[gas_path]
gas_heat_resistance += sm_gas.heat_resistance * gas_percentage[gas_path]
gas_heat_power_generation += sm_gas.heat_power_generation * gas_percentage[gas_path]
@@ -637,7 +667,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
external_power_trickle -= min(additive_power[SM_POWER_EXTERNAL_TRICKLE], external_power_trickle)
additive_power[SM_POWER_EXTERNAL_IMMEDIATE] = external_power_immediate
external_power_immediate = 0
- additive_power[SM_POWER_HEAT] = gas_heat_power_generation * absorbed_gasmix.temperature / 6
+ additive_power[SM_POWER_HEAT] = gas_heat_power_generation * absorbed_gasmix.temperature * GAS_HEAT_POWER_SCALING_COEFFICIENT
additive_power[SM_POWER_HEAT] && log_activation(who = "environmental factors")
// I'm sorry for this, but we need to calculate power lost immediately after power gain.
@@ -660,6 +690,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
if(internal_energy && !activation_logged)
stack_trace("Supermatter powered for the first time without being logged. Internal energy factors: [json_encode(internal_energy_factors)]")
activation_logged = TRUE // so we dont spam the log.
+ else if(!internal_energy)
+ last_power_zap = world.time
return additive_power
/** Log when the supermatter is activated for the first time.
@@ -685,24 +717,24 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
activation_logged = TRUE
/**
- * Perform calculation for the main zap power multiplier.
+ * Perform calculation for the main zap power transmission rate in W/MeV.
* Description of each factors can be found in the defines.
*
* Updates:
- * [/obj/machinery/power/supermatter_crystal/var/zap_multiplier]
+ * [/obj/machinery/power/supermatter_crystal/var/zap_transmission_rate]
*
* Returns: The factors that have influenced the calculation. list[FACTOR_DEFINE] = number
*/
-/obj/machinery/power/supermatter_crystal/proc/calculate_zap_multiplier()
- var/list/additive_transmission = list()
- additive_transmission[SM_ZAP_BASE] = 1
- additive_transmission[SM_ZAP_GAS] = gas_power_transmission
+/obj/machinery/power/supermatter_crystal/proc/calculate_zap_transmission_rate()
+ var/list/additive_transmission_rate = list()
+ additive_transmission_rate[SM_ZAP_BASE] = BASE_POWER_TRANSMISSION_RATE
+ additive_transmission_rate[SM_ZAP_GAS] = BASE_POWER_TRANSMISSION_RATE * gas_power_transmission_rate
- zap_multiplier = 0
- for (var/transmission_types in additive_transmission)
- zap_multiplier += additive_transmission[transmission_types]
- zap_multiplier = max(zap_multiplier, 0)
- return additive_transmission
+ zap_transmission_rate = 0
+ for (var/transmission_types in additive_transmission_rate)
+ zap_transmission_rate += additive_transmission_rate[transmission_types]
+ zap_transmission_rate = max(zap_transmission_rate, 0)
+ return additive_transmission_rate
/**
* Perform calculation for the waste multiplier.
@@ -836,7 +868,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
delamination_strategy.on_select(src)
return TRUE
-/obj/machinery/proc/supermatter_zap(atom/zapstart = src, range = 5, zap_str = 4000, zap_flags = ZAP_SUPERMATTER_FLAGS, list/targets_hit = list(), zap_cutoff = 1500, power_level = 0, zap_icon = DEFAULT_ZAP_ICON_STATE, color = null)
+/obj/machinery/proc/supermatter_zap(atom/zapstart = src, range = 5, zap_str = 3.2e6, zap_flags = ZAP_SUPERMATTER_FLAGS, list/targets_hit = list(), zap_cutoff = 1.2e6, power_level = 0, zap_icon = DEFAULT_ZAP_ICON_STATE, color = null)
if(QDELETED(zapstart))
return
. = zapstart.dir
@@ -931,13 +963,13 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
//Going boom should be rareish
if(prob(80))
zap_flags &= ~ZAP_MACHINE_EXPLOSIVE
- if(target_type == COIL)
- var/multi = 2
- switch(power_level)//Between 7k and 9k it's 4, above that it's 8
+ if(target_type == COIL || target_type == ROD)
+ var/multi = 1
+ switch(power_level)//Between 7k and 9k it's 2, above that it's 4
if(SEVERE_POWER_PENALTY_THRESHOLD to CRITICAL_POWER_PENALTY_THRESHOLD)
- multi = 4
+ multi = 2
if(CRITICAL_POWER_PENALTY_THRESHOLD to INFINITY)
- multi = 8
+ multi = 4
if(zap_flags & ZAP_SUPERMATTER_FLAGS)
var/remaining_power = target.zap_act(zap_str * multi, zap_flags)
zap_str = remaining_power / multi //Coils should take a lot out of the power of the zap
diff --git a/code/modules/power/supermatter/supermatter_extra_effects.dm b/code/modules/power/supermatter/supermatter_extra_effects.dm
index 7fe56d9c2d4..efd84c677fa 100644
--- a/code/modules/power/supermatter/supermatter_extra_effects.dm
+++ b/code/modules/power/supermatter/supermatter_extra_effects.dm
@@ -91,6 +91,7 @@
/obj/machinery/power/supermatter_crystal/proc/handle_high_power()
if(internal_energy <= POWER_PENALTY_THRESHOLD && damage <= danger_point) //If the power is above 5000 or if the damage is above 550
+ last_high_energy_zap = world.time //Prevent oddly high initial zap due to high energy zaps not getting triggered via too low energy.
return
var/range = 4
zap_cutoff = 1500
@@ -99,7 +100,7 @@
var/temp = absorbed_gasmix.temperature
if(pressure > 0 && temp > 0)
//You may be able to freeze the zapstate of the engine with good planning, we'll see
- zap_cutoff = clamp(3000 - (internal_energy * total_moles / 10) / temp, 350, 3000)//If the core is cold, it's easier to jump, ditto if there are a lot of mols
+ zap_cutoff = clamp(1.2e6 - (internal_energy * total_moles * 40) / temp, 1.4e5, 1.2e6)//If the core is cold, it's easier to jump, ditto if there are a lot of mols
//We should always be able to zap our way out of the default enclosure
//See supermatter_zap() for more details
range = clamp(internal_energy / pressure * 10, 2, 7)
@@ -128,9 +129,10 @@
if(zap_count >= 1)
playsound(loc, 'sound/weapons/emitter2.ogg', 100, TRUE, extrarange = 10)
+ var/delta_time = min((world.time - last_high_energy_zap) * 0.1, 16)
for(var/i in 1 to zap_count)
- supermatter_zap(src, range, clamp(internal_energy*2, 4000, 20000), flags, zap_cutoff = src.zap_cutoff, power_level = internal_energy, zap_icon = src.zap_icon)
-
+ supermatter_zap(src, range, clamp(internal_energy * 3200, 6.4e6, 3.2e7) * delta_time, flags, zap_cutoff = src.zap_cutoff * delta_time, power_level = internal_energy, zap_icon = src.zap_icon)
+ last_high_energy_zap = world.time
if(prob(5))
supermatter_anomaly_gen(src, FLUX_ANOMALY, rand(5, 10))
if(prob(5))
diff --git a/code/modules/power/supermatter/supermatter_gas.dm b/code/modules/power/supermatter/supermatter_gas.dm
index 141f78a38b8..df8ef8e5b4f 100644
--- a/code/modules/power/supermatter/supermatter_gas.dm
+++ b/code/modules/power/supermatter/supermatter_gas.dm
@@ -17,33 +17,40 @@
// Positive is true if more of the amount is a good thing.
var/list/numeric_data = list()
if(sm_gas.power_transmission)
+ var/list/si_derived_data = siunit_isolated(sm_gas.power_transmission * BASE_POWER_TRANSMISSION_RATE, "W/MeV", 2)
numeric_data += list(list(
- "name" = "Power Transmission",
- "amount" = sm_gas.power_transmission,
+ "name" = "Power Transmission Bonus",
+ "amount" = si_derived_data["coefficient"],
+ "unit" = si_derived_data["unit"],
"positive" = TRUE,
))
if(sm_gas.heat_modifier)
numeric_data += list(list(
"name" = "Waste Multiplier",
- "amount" = sm_gas.heat_modifier,
+ "amount" = 100 * sm_gas.heat_modifier,
+ "unit" = "%",
"positive" = FALSE,
))
if(sm_gas.heat_resistance)
numeric_data += list(list(
"name" = "Heat Resistance",
- "amount" = sm_gas.heat_resistance,
+ "amount" = 100 * sm_gas.heat_resistance,
+ "unit" = "%",
"positive" = TRUE,
))
if(sm_gas.heat_power_generation)
+ var/list/si_derived_data = siunit_isolated(sm_gas.heat_power_generation * GAS_HEAT_POWER_SCALING_COEFFICIENT * 1e7 / SSair.wait, "eV/K/s", 2)
numeric_data += list(list(
"name" = "Heat Power Gain",
- "amount" = sm_gas.heat_power_generation,
+ "amount" = si_derived_data["coefficient"],
+ "unit" = si_derived_data["unit"],
"positive" = TRUE,
))
if(sm_gas.powerloss_inhibition)
numeric_data += list(list(
"name" = "Power Decay Negation",
- "amount" = sm_gas.powerloss_inhibition,
+ "amount" = 100 * sm_gas.powerloss_inhibition,
+ "unit" = "%",
"positive" = TRUE,
))
singular_gas_data["numeric_data"] = numeric_data
@@ -59,8 +66,7 @@ GLOBAL_LIST_INIT(sm_gas_behavior, init_sm_gas())
/datum/sm_gas
/// Path of the [/datum/gas] involved with this interaction.
var/gas_path
-
- /// Influences zap power without interfering with the crystal's own energy.
+ /// Influences zap power without interfering with the crystal's own energy. Gets scaled by [BASE_POWER_TRANSMISSION_RATE].
var/power_transmission = 0
/// How much more waste heat and gas the SM generates.
var/heat_modifier = 0
@@ -216,7 +222,7 @@ GLOBAL_LIST_INIT(sm_gas_behavior, init_sm_gas())
sm.supermatter_zap(
sm,
range = 6,
- zap_str = clamp(sm.internal_energy * 2, 4000, 20000),
+ zap_str = clamp(sm.internal_energy * 1600, 3.2e6, 1.6e7),
zap_flags = ZAP_MOB_STUN,
zap_cutoff = sm.zap_cutoff,
power_level = sm.internal_energy,
diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm
index 098ff7ceaee..3cf040b76ef 100644
--- a/code/modules/power/tesla/coil.dm
+++ b/code/modules/power/tesla/coil.dm
@@ -1,7 +1,5 @@
// zap needs to be over this amount to get power
-#define TESLA_COIL_THRESHOLD 80
-// each zap power unit produces 400 joules
-#define ZAP_TO_ENERGY(p) (joules_to_energy((p) * 400))
+#define TESLA_COIL_THRESHOLD 32000
/obj/machinery/power/energy_accumulator/tesla_coil
name = "tesla coil"
@@ -107,7 +105,7 @@
power /= 10
zap_buckle_check(power)
var/power_removed = powernet ? power * input_power_multiplier : power
- stored_energy += max(ZAP_TO_ENERGY(power_removed - TESLA_COIL_THRESHOLD), 0)
+ stored_energy += max(joules_to_energy(power_removed - TESLA_COIL_THRESHOLD), 0)
return max(power - power_removed, 0) //You get back the amount we didn't use
/obj/machinery/power/energy_accumulator/tesla_coil/proc/zap()
@@ -170,10 +168,9 @@
if(anchored && !panel_open)
flick("grounding_rodhit", src)
zap_buckle_check(power)
- stored_energy += ZAP_TO_ENERGY(power)
+ stored_energy += joules_to_energy(power)
return 0
else
. = ..()
#undef TESLA_COIL_THRESHOLD
-#undef ZAP_TO_ENERGY
diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm
index b21938e2608..7ee8c0085c9 100644
--- a/code/modules/power/tesla/energy_ball.dm
+++ b/code/modules/power/tesla/energy_ball.dm
@@ -1,5 +1,5 @@
-#define TESLA_DEFAULT_POWER 1738260
-#define TESLA_MINI_POWER 869130
+#define TESLA_DEFAULT_POWER 6.95304e8
+#define TESLA_MINI_POWER 3.47652e8
//Zap constants, speeds up targeting
#define BIKE (COIL + 1)
#define COIL (ROD + 1)
@@ -205,7 +205,7 @@
if(!(zap_flags & ZAP_ALLOW_DUPLICATES))
LAZYSET(shocked_targets, source, TRUE) //I don't want no null refs in my list yeah?
. = source.dir
- if(power < 1000)
+ if(power < 4e5)
return
/*
@@ -334,7 +334,7 @@
var/mob/living/closest_mob = closest_atom
ADD_TRAIT(closest_mob, TRAIT_BEING_SHOCKED, WAS_SHOCKED)
addtimer(TRAIT_CALLBACK_REMOVE(closest_mob, TRAIT_BEING_SHOCKED, WAS_SHOCKED), 1 SECONDS)
- var/shock_damage = (zap_flags & ZAP_MOB_DAMAGE) ? (min(round(power/600), 90) + rand(-5, 5)) : 0
+ var/shock_damage = (zap_flags & ZAP_MOB_DAMAGE) ? (min(round(power/2.4e5), 90) + rand(-5, 5)) : 0
closest_mob.electrocute_act(shock_damage, source, 1, SHOCK_TESLA | ((zap_flags & ZAP_MOB_STUN) ? NONE : SHOCK_NOSTUN))
if(issilicon(closest_mob))
var/mob/living/silicon/S = closest_mob
diff --git a/code/modules/procedural_mapping/mapGenerators/asteroid.dm b/code/modules/procedural_mapping/mapGenerators/asteroid.dm
index ab2bc6f2ca4..bf6c84ebf88 100644
--- a/code/modules/procedural_mapping/mapGenerators/asteroid.dm
+++ b/code/modules/procedural_mapping/mapGenerators/asteroid.dm
@@ -22,7 +22,7 @@
spawnableAtoms = list(
/mob/living/basic/mining/basilisk = 10,
/mob/living/basic/mining/goliath/ancient = 10,
- /mob/living/simple_animal/hostile/asteroid/hivelord = 10,
+ /mob/living/basic/mining/hivelord = 10,
)
diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm
index 6439b78a9bd..2b62416fe7f 100644
--- a/code/modules/projectiles/guns/ballistic/revolver.dm
+++ b/code/modules/projectiles/guns/ballistic/revolver.dm
@@ -275,10 +275,15 @@
user.visible_message(span_danger("[user.name]'s soul is captured by \the [src]!"), span_userdanger("You've lost the gamble! Your soul is forfeit!"))
/obj/item/gun/ballistic/revolver/reverse //Fires directly at its user... unless the user is a clown, of course.
- name = "\improper Syndicate Revolver"
clumsy_check = FALSE
icon_state = "revolversyndie"
+/obj/item/gun/ballistic/revolver/reverse/Initialize(mapload)
+ . = ..()
+ var/obj/item/gun/ballistic/revolver/syndicate/syndie_revolver = /obj/item/gun/ballistic/revolver/syndicate
+ name = initial(syndie_revolver.name)
+ desc = initial(syndie_revolver.desc)
+
/obj/item/gun/ballistic/revolver/reverse/can_trigger_gun(mob/living/user, akimbo_usage)
if(akimbo_usage)
return FALSE
diff --git a/code/modules/projectiles/guns/energy/energy_gun.dm b/code/modules/projectiles/guns/energy/energy_gun.dm
index 3fd1e7c1949..cb0b5862e16 100644
--- a/code/modules/projectiles/guns/energy/energy_gun.dm
+++ b/code/modules/projectiles/guns/energy/energy_gun.dm
@@ -9,6 +9,18 @@
ammo_x_offset = 3
dual_wield_spread = 60
+/obj/item/gun/energy/e_gun/Initialize(mapload)
+ . = ..()
+ // Only actual eguns can be converted
+ if(type != /obj/item/gun/energy/e_gun)
+ return
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/advancedegun, /datum/crafting_recipe/tempgun, /datum/crafting_recipe/beam_rifle)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/gun/energy/e_gun/add_seclight_point()
AddComponent(/datum/component/seclite_attachable, \
light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', \
diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
index 8d9a29d3b80..06e82a37aae 100644
--- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
+++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
@@ -16,6 +16,19 @@
var/list/modkits = list()
gun_flags = NOT_A_REAL_GUN
+
+/obj/item/gun/energy/recharge/kinetic_accelerator/Initialize(mapload)
+ . = ..()
+ // Only actual KAs can be converted
+ if(type != /obj/item/gun/energy/recharge/kinetic_accelerator)
+ return
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/ebow)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/gun/energy/recharge/kinetic_accelerator/apply_fantasy_bonuses(bonus)
. = ..()
max_mod_capacity = modify_fantasy_variable("max_mod_capacity", max_mod_capacity, bonus * 10)
diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm
index dafaaa6a7de..0409f2fe037 100644
--- a/code/modules/projectiles/guns/energy/laser.dm
+++ b/code/modules/projectiles/guns/energy/laser.dm
@@ -9,6 +9,18 @@
ammo_x_offset = 1
shaded_charge = 1
+/obj/item/gun/energy/laser/Initialize(mapload)
+ . = ..()
+ // Only actual lasguns can be converted
+ if(type != /obj/item/gun/energy/laser)
+ return
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/xraylaser, /datum/crafting_recipe/hellgun, /datum/crafting_recipe/ioncarbine, /datum/crafting_recipe/decloner)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/obj/item/gun/energy/laser/practice
name = "practice laser gun"
desc = "A modified version of the basic laser gun, this one fires less concentrated energy bolts designed for target practice."
diff --git a/code/modules/projectiles/projectile/energy/tesla.dm b/code/modules/projectiles/projectile/energy/tesla.dm
index 9afb816088f..687bd1b8e73 100644
--- a/code/modules/projectiles/projectile/energy/tesla.dm
+++ b/code/modules/projectiles/projectile/energy/tesla.dm
@@ -5,7 +5,7 @@
damage = 10 //A worse lasergun
var/zap_flags = ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_LOW_POWER_GEN
var/zap_range = 3
- var/power = 10000
+ var/power = 4e6
/obj/projectile/energy/tesla/on_hit(atom/target)
. = ..()
@@ -22,7 +22,7 @@
/obj/projectile/energy/tesla/cannon
name = "tesla orb"
- power = 20000
+ power = 8e6
damage = 15 //Mech man big
/obj/projectile/energy/tesla_cannon
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
index afe59235478..c8da91b9dde 100644
--- a/code/modules/projectiles/projectile/magic.dm
+++ b/code/modules/projectiles/projectile/magic.dm
@@ -481,7 +481,7 @@
speed = 0.3
/// The power of the zap itself when it electrocutes someone
- var/zap_power = 20000
+ var/zap_power = 8e6
/// The range of the zap itself when it electrocutes someone
var/zap_range = 15
/// The flags of the zap itself when it electrocutes someone
@@ -503,7 +503,7 @@
return ..()
/obj/projectile/magic/aoe/lightning/no_zap
- zap_power = 10000
+ zap_power = 4e6
zap_range = 4
zap_flags = ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_LOW_POWER_GEN
diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm
index 8de1d98cc2e..110107d103f 100644
--- a/code/modules/reagents/chemistry/reagents.dm
+++ b/code/modules/reagents/chemistry/reagents.dm
@@ -7,6 +7,10 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
if (length(initial(R.name)))
.[ckey(initial(R.name))] = t
+GLOBAL_LIST_INIT(blacklisted_metalgen_types, typecacheof(list(
+ /turf/closed/indestructible, //indestructible turfs should be indestructible, metalgen transmutation to plasma allows them to be destroyed
+ /turf/open/indestructible
+)))
//Various reagents
//Toxin & acid reagents
diff --git a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm
index f67b813be0c..b81e1600bbf 100644
--- a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm
@@ -57,6 +57,20 @@
booze_power *= 0.7
if(HAS_TRAIT(drinker, TRAIT_LIGHT_DRINKER))
booze_power *= 2
+
+ // water will dilute alcohol effects
+ var/total_water_volume = 0
+ var/total_alcohol_volume = 0
+ for(var/datum/reagent/water/sobriety in drinker.reagents.reagent_list)
+ total_water_volume += sobriety.volume
+
+ for(var/datum/reagent/consumable/ethanol/alcohol in drinker.reagents.reagent_list)
+ total_alcohol_volume += alcohol.volume
+
+ var/combined_dilute_volume = total_alcohol_volume + total_water_volume
+ if(combined_dilute_volume) // safety check to prevent division by zero
+ booze_power *= (total_alcohol_volume / combined_dilute_volume)
+
// Volume, power, and server alcohol rate effect how quickly one gets drunk
drinker.adjust_drunk_effect(sqrt(volume) * booze_power * ALCOHOL_RATE * REM * seconds_per_tick * 0.25) // SKYRAT EDIT CHANGE - Alcohol Tolerance - Original: (sqrt(volume) * booze_power * ALCOHOL_RATE * REM * seconds_per_tick)
if(boozepwr > 0)
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index 1e0559d6034..17867389c3d 100644
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -272,9 +272,9 @@
color = "#FFFFFF" // rgb: 255, 255, 255
taste_mult = 1.5 // stop sugar drowning out other flavours
nutriment_factor = 2
- metabolization_rate = 2 * REAGENTS_METABOLISM
+ metabolization_rate = 5 * REAGENTS_METABOLISM
creation_purity = 1 // impure base reagents are a big no-no
- overdose_threshold = 100 // Hyperglycaemic shock
+ overdose_threshold = 120 // Hyperglycaemic shock
taste_description = "sweetness"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
default_container = /obj/item/reagent_containers/condiment/sugar
@@ -286,11 +286,11 @@
/datum/reagent/consumable/sugar/overdose_start(mob/living/M)
to_chat(M, span_userdanger("You go into hyperglycaemic shock! Lay off the twinkies!"))
- M.AdjustSleeping(600)
+ M.AdjustSleeping(20 SECONDS)
. = TRUE
/datum/reagent/consumable/sugar/overdose_process(mob/living/M, seconds_per_tick, times_fired)
- M.AdjustSleeping(40 * REM * seconds_per_tick)
+ M.adjust_drowsiness_up_to((5 SECONDS * REM * seconds_per_tick), 60 SECONDS)
..()
. = TRUE
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 2a46d537233..dddf966be72 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -292,6 +292,7 @@
. = ..()
if(affected_mob.blood_volume)
affected_mob.blood_volume += 0.1 * REM * seconds_per_tick // water is good for you!
+ affected_mob.adjust_drunk_effect(-0.25 * REM * seconds_per_tick) // and even sobers you up slowly!!
// For weird backwards situations where water manages to get added to trays nutrients, as opposed to being snowflaked away like usual.
/datum/reagent/water/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user)
@@ -2686,13 +2687,16 @@
metal_morph(exposed_turf)
///turn an object into a special material
-/datum/reagent/metalgen/proc/metal_morph(atom/A)
+/datum/reagent/metalgen/proc/metal_morph(atom/target)
var/metal_ref = data["material"]
if(!metal_ref)
return
+ if(is_type_in_typecache(target, GLOB.blacklisted_metalgen_types)) //some stuff can lead to exploits if transmuted
+ return
+
var/metal_amount = 0
- var/list/materials_to_transmute = A.get_material_composition(BREAKDOWN_INCLUDE_ALCHEMY)
+ var/list/materials_to_transmute = target.get_material_composition(BREAKDOWN_INCLUDE_ALCHEMY)
for(var/metal_key in materials_to_transmute) //list with what they're made of
metal_amount += materials_to_transmute[metal_key]
@@ -2700,9 +2704,9 @@
metal_amount = default_material_amount //some stuff doesn't have materials at all. To still give them properties, we give them a material. Basically doesn't exist
var/list/metal_dat = list((metal_ref) = metal_amount)
- A.material_flags = applied_material_flags
- A.set_custom_materials(metal_dat)
- ADD_TRAIT(A, TRAIT_MAT_TRANSMUTED, type)
+ target.material_flags = applied_material_flags
+ target.set_custom_materials(metal_dat)
+ ADD_TRAIT(target, TRAIT_MAT_TRANSMUTED, type)
/datum/reagent/gravitum
name = "Gravitum"
diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
index 707a1dca350..9083de70902 100644
--- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
+++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
@@ -542,9 +542,9 @@
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_DANGEROUS
/datum/chemical_reaction/reagent_explosion/teslium_lightning/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
- var/T1 = created_volume * 20 //100 units : Zap 3 times, with powers 2000/5000/12000. Tesla revolvers have a power of 10000 for comparison.
- var/T2 = created_volume * 50
- var/T3 = created_volume * 120
+ var/T1 = created_volume * 8e3 //100 units : Zap 3 times, with powers 8e5/2e6/4.8e6. Tesla revolvers have a power of 10000 for comparison.
+ var/T2 = created_volume * 2e4
+ var/T3 = created_volume * 4.8e4
var/added_delay = 0.5 SECONDS
if(created_volume >= 75)
addtimer(CALLBACK(src, PROC_REF(zappy_zappy), holder, T1), added_delay)
diff --git a/code/modules/reagents/reagent_containers/cups/glassbottle.dm b/code/modules/reagents/reagent_containers/cups/glassbottle.dm
index e2f445c6a1a..e204c6803fb 100644
--- a/code/modules/reagents/reagent_containers/cups/glassbottle.dm
+++ b/code/modules/reagents/reagent_containers/cups/glassbottle.dm
@@ -40,6 +40,12 @@
tool_behaviour = TOOL_ROLLINGPIN // Used to knock out the Chef.
toolspeed = 1.3 //it's a little awkward to use, but it's a cylinder alright.
+/obj/item/reagent_containers/cup/glass/bottle/Initialize(mapload, vol)
+ . = ..()
+ AddComponent(/datum/component/slapcrafting,\
+ slapcraft_recipes = list(/datum/crafting_recipe/molotov)\
+ )
+
/obj/item/reagent_containers/cup/glass/bottle/small
name = "small glass bottle"
desc = "This blank bottle is unyieldingly anonymous, offering no clues to its contents."
diff --git a/code/modules/reagents/reagent_containers/cups/soda.dm b/code/modules/reagents/reagent_containers/cups/soda.dm
index 4908942b2c0..5bf0eb782c5 100644
--- a/code/modules/reagents/reagent_containers/cups/soda.dm
+++ b/code/modules/reagents/reagent_containers/cups/soda.dm
@@ -21,6 +21,12 @@
/// If the can hasn't been opened yet, this is the measure of how fizzed up it is from being shaken or thrown around. When opened, this is rolled as a percentage chance to burst
var/fizziness = 0
+/obj/item/reagent_containers/cup/soda_cans/Initialize(mapload, vol)
+ . = ..()
+ AddComponent(/datum/component/slapcrafting,\
+ slapcraft_recipes = list(/datum/crafting_recipe/improv_explosive)\
+ )
+
/obj/item/reagent_containers/cup/soda_cans/random/Initialize(mapload)
..()
var/T = pick(subtypesof(/obj/item/reagent_containers/cup/soda_cans) - /obj/item/reagent_containers/cup/soda_cans/random)
diff --git a/code/modules/religion/religion_sects.dm b/code/modules/religion/religion_sects.dm
index a322303b00d..9075a656ae9 100644
--- a/code/modules/religion/religion_sects.dm
+++ b/code/modules/religion/religion_sects.dm
@@ -55,8 +55,8 @@
/// Activates once selected and on newjoins, oriented around people who become holy.
/datum/religion_sect/proc/on_conversion(mob/living/chap)
SHOULD_CALL_PARENT(TRUE)
- to_chat(chap, "\"[quote]\"")
- to_chat(chap, "[desc]")
+ to_chat(chap, span_boldnotice("\"[quote]\""))
+ to_chat(chap, span_notice("[desc]"))
/// Activates if religious sect is reset by admins, should clean up anything you added on conversion.
/datum/religion_sect/proc/on_deconversion(mob/living/chap)
@@ -66,17 +66,17 @@
to_chat(chap, span_notice("Return to an altar to reform your sect."))
/// Returns TRUE if the item can be sacrificed. Can be modified to fit item being tested as well as person offering. Returning TRUE will stop the attackby sequence and proceed to on_sacrifice.
-/datum/religion_sect/proc/can_sacrifice(obj/item/I, mob/living/chap)
+/datum/religion_sect/proc/can_sacrifice(obj/item/sacrifice, mob/living/chap)
. = TRUE
if(chap.mind.holy_role == HOLY_ROLE_DEACON)
to_chat(chap, "You are merely a deacon of [GLOB.deity], and therefore cannot perform rites.")
return
- if(!is_type_in_typecache(I,desired_items_typecache))
+ if(!is_type_in_typecache(sacrifice, desired_items_typecache))
return FALSE
/// Activates when the sect sacrifices an item. This proc has NO bearing on the attackby sequence of other objects when used in conjunction with the religious_tool component.
-/datum/religion_sect/proc/on_sacrifice(obj/item/I, mob/living/chap)
- return adjust_favor(default_item_favor,chap)
+/datum/religion_sect/proc/on_sacrifice(obj/item/sacrifice, mob/living/chap)
+ return adjust_favor(default_item_favor, chap)
/// Returns a description for religious tools
/datum/religion_sect/proc/tool_examine(mob/living/holy_creature)
@@ -89,7 +89,7 @@
. = favor //if favor = 5 and we want to subtract 10, we'll only be able to subtract 5
if((favor + amount > max_favor))
. = (max_favor-favor) //if favor = 5 and we want to add 10 with a max of 10, we'll only be able to add 5
- favor = clamp(0,max_favor, favor+amount)
+ favor = clamp(0, max_favor, favor+amount)
/// Sets favor to a specific amount. Can provide optional features based on a user.
/datum/religion_sect/proc/set_favor(amount = 0, mob/living/chap)
@@ -190,16 +190,17 @@
blessed.add_mood_event("blessing", /datum/mood_event/blessing)
return TRUE
-/datum/religion_sect/mechanical/on_sacrifice(obj/item/I, mob/living/chap)
- var/obj/item/stock_parts/cell/the_cell = I
- if(!istype(the_cell)) //how...
+/datum/religion_sect/mechanical/on_sacrifice(obj/item/stock_parts/cell/power_cell, mob/living/chap)
+ if(!istype(power_cell))
return
- if(the_cell.charge < 300)
- to_chat(chap,span_notice("[GLOB.deity] does not accept pity amounts of power."))
+
+ if(power_cell.charge < 300)
+ to_chat(chap, span_notice("[GLOB.deity] does not accept pity amounts of power."))
return
- adjust_favor(round(the_cell.charge/300), chap)
- to_chat(chap, span_notice("You offer [the_cell]'s power to [GLOB.deity], pleasing them."))
- qdel(I)
+
+ adjust_favor(round(power_cell.charge/300), chap)
+ to_chat(chap, span_notice("You offer [power_cell]'s power to [GLOB.deity], pleasing them."))
+ qdel(power_cell)
return TRUE
/**** Pyre God ****/
diff --git a/code/modules/research/designs/biogenerator_designs.dm b/code/modules/research/designs/biogenerator_designs.dm
index f07ef21a8e7..14d5c12eb43 100644
--- a/code/modules/research/designs/biogenerator_designs.dm
+++ b/code/modules/research/designs/biogenerator_designs.dm
@@ -185,3 +185,11 @@
materials = list(/datum/material/biomass = 1)
build_path = /obj/item/rollingpaper
category = list(RND_CATEGORY_INITIAL, RND_CATEGORY_BIO_MATERIALS)
+
+/datum/design/candle
+ name = "Candle"
+ id = "candle"
+ build_type = BIOGENERATOR
+ materials = list(/datum/material/biomass = 3)
+ build_path = /obj/item/flashlight/flare/candle
+ category = list(RND_CATEGORY_INITIAL, RND_CATEGORY_BIO_MATERIALS)
diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm
index 2bb779e318b..285878e7f26 100644
--- a/code/modules/research/designs/medical_designs.dm
+++ b/code/modules/research/designs/medical_designs.dm
@@ -1114,6 +1114,13 @@
surgery = /datum/surgery/advanced/wing_reconstruction
research_icon_state = "surgery_chest"
+/datum/design/surgery/advanced_plastic_surgery
+ name = "Advanced Plastic Surgery"
+ desc = "An advanced form of the plastic surgery, allowing oneself to remodel someone's face and voice based off a picture of someones face"
+ surgery = /datum/surgery/plastic_surgery/advanced
+ id = "surgery_advanced_plastic_surgery"
+ research_icon_state = "surgery_head"
+
/datum/design/surgery/experimental_dissection
name = "Experimental Dissection"
desc = "An experimental surgical procedure that dissects bodies in exchange for research points at ancient R&D consoles."
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index 2ec692f0575..3f64efe851e 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -2368,3 +2368,15 @@
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
hidden = TRUE
experimental = TRUE
+
+/datum/techweb_node/advanced_plastic_surgery
+ id = "plastic_surgery"
+ display_name = "Advanced Plastic Surgery"
+ description = "A Procedure long lost due to licensing problems now once again available."
+ prereq_ids = list("base")
+ design_ids = list(
+ "surgery_advanced_plastic_surgery"
+ )
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
+ hidden = TRUE
+ experimental = TRUE
diff --git a/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm b/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm
index abb764d0689..ece96fd41e0 100644
--- a/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm
+++ b/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm
@@ -223,7 +223,7 @@
/datum/reagent/consumable/corn_syrup = -6,
/datum/reagent/sulfur = -3) //sulfur repels snakes according to professor google.
- resulting_atoms = list(/mob/living/simple_animal/hostile/retaliate/snake = 1)
+ resulting_atoms = list(/mob/living/basic/snake = 1)
///////////////////////////////////////////
diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm
index aba37b37a55..44c13e39c76 100644
--- a/code/modules/shuttle/supply.dm
+++ b/code/modules/shuttle/supply.dm
@@ -61,17 +61,61 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
/obj/docking_port/mobile/supply/proc/check_blacklist(areaInstances)
for(var/place in areaInstances)
var/area/shuttle/shuttle_area = place
- for(var/turf/shuttle_turf in shuttle_area)
+ for(var/turf/shuttle_turf in shuttle_area.get_contained_turfs())
for(var/atom/passenger in shuttle_turf.get_all_contents())
if((is_type_in_typecache(passenger, GLOB.blacklisted_cargo_types) || HAS_TRAIT(passenger, TRAIT_BANNED_FROM_CARGO_SHUTTLE)) && !istype(passenger, /obj/docking_port))
return FALSE
return TRUE
+/// Returns anything on the cargo blacklist found within areas_to_check back to the turf of the home docking port via Centcom branded supply pod.
+/obj/docking_port/mobile/supply/proc/return_blacklisted_things_home(list/area/areas_to_check, obj/docking_port/stationary/home)
+ var/list/stuff_to_send_home = list()
+ for(var/area/shuttle_area as anything in areas_to_check)
+ for(var/turf/shuttle_turf in shuttle_area.get_contained_turfs())
+ for(var/atom/passenger in shuttle_turf.get_all_contents())
+ if((is_type_in_typecache(passenger, GLOB.blacklisted_cargo_types) || HAS_TRAIT(passenger, TRAIT_BANNED_FROM_CARGO_SHUTTLE)) && !istype(passenger, /obj/docking_port))
+ stuff_to_send_home += passenger
+
+ if(!length(stuff_to_send_home))
+ return FALSE
+
+ var/obj/structure/closet/supplypod/centcompod/et_go_home = new()
+
+ for(var/atom/movable/et as anything in stuff_to_send_home)
+ et.forceMove(et_go_home)
+
+ new /obj/effect/pod_landingzone(get_turf(home), et_go_home)
+
+ return stuff_to_send_home
+
/obj/docking_port/mobile/supply/request(obj/docking_port/stationary/S)
if(mode != SHUTTLE_IDLE)
return 2
return ..()
+/obj/docking_port/mobile/supply/check_dock(obj/docking_port/stationary/S, silent)
+ . = ..()
+
+ if(!.)
+ return
+
+ // If we're not trying to dock at Centcom, we don't care.
+ if(S.shuttle_id != "cargo_away")
+ return
+
+ // Else we are docking at Centcom, check the blacklist to make sure no contraband was put onto the shuttle mid-transit.
+ // If there's anything contrabandy, send these items back to the origin docking port.
+ // This is a sort of catch-all Centcom exploit check.
+ var/list/stuff_sent_home = return_blacklisted_things_home(shuttle_areas, previous)
+ if(!length(stuff_sent_home))
+ return
+
+ for(var/atom/thing_sent_home as anything in stuff_sent_home)
+ investigate_log("Blacklisted item found on in-transit Cargo Shuttle: [thing_sent_home] ([thing_sent_home.type])", INVESTIGATE_CARGO)
+
+ message_admins("Blacklisted item found on in-transit Cargo Shuttle. See cargo logs for more details.")
+ SSshuttle.centcom_message = "Contraband found on Cargo Shuttle. This has been returned via drop pod."
+
/obj/docking_port/mobile/supply/initiate_docking()
if(getDockedId() == "cargo_away") // Buy when we leave home.
buy()
diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm
index 966f618376d..f03cd4927f8 100644
--- a/code/modules/spells/spell.dm
+++ b/code/modules/spells/spell.dm
@@ -180,11 +180,6 @@
to_chat(owner, span_warning("Some form of antimagic is preventing you from casting [src]!"))
return FALSE
- if(!(spell_requirements & SPELL_CASTABLE_WHILE_PHASED) && HAS_TRAIT(owner, TRAIT_MAGICALLY_PHASED))
- if(feedback)
- to_chat(owner, span_warning("[src] cannot be cast unless you are completely manifested in the material plane!"))
- return FALSE
-
if(!try_invoke(owner, feedback = feedback))
return FALSE
diff --git a/code/modules/spells/spell_types/jaunt/_jaunt.dm b/code/modules/spells/spell_types/jaunt/_jaunt.dm
index 4a94f03c041..207a7ed8b5b 100644
--- a/code/modules/spells/spell_types/jaunt/_jaunt.dm
+++ b/code/modules/spells/spell_types/jaunt/_jaunt.dm
@@ -62,7 +62,7 @@
var/obj/effect/dummy/phased_mob/jaunt = new jaunt_type(loc_override || get_turf(jaunter), jaunter)
RegisterSignal(jaunt, COMSIG_MOB_EJECTED_FROM_JAUNT, PROC_REF(on_jaunt_exited))
- spell_requirements |= SPELL_CASTABLE_WHILE_PHASED
+ check_flags &= ~AB_CHECK_PHASED
jaunter.add_traits(list(TRAIT_MAGICALLY_PHASED, TRAIT_RUNECHAT_HIDDEN, TRAIT_WEATHER_IMMUNE), REF(src))
// Don't do the feedback until we have runechat hidden.
// Otherwise the text will follow the jaunt holder, which reveals where our caster is travelling.
@@ -106,7 +106,7 @@
*/
/datum/action/cooldown/spell/jaunt/proc/on_jaunt_exited(obj/effect/dummy/phased_mob/jaunt, mob/living/unjaunter)
SHOULD_CALL_PARENT(TRUE)
- spell_requirements &= ~SPELL_CASTABLE_WHILE_PHASED
+ check_flags |= AB_CHECK_PHASED
unjaunter.remove_traits(list(TRAIT_MAGICALLY_PHASED, TRAIT_RUNECHAT_HIDDEN, TRAIT_WEATHER_IMMUNE), REF(src))
// This needs to happen at the end, after all the traits and stuff is handled
SEND_SIGNAL(unjaunter, COMSIG_MOB_AFTER_EXIT_JAUNT, src)
diff --git a/code/modules/spells/spell_types/self/splattercasting_spell.dm b/code/modules/spells/spell_types/self/splattercasting_spell.dm
index 1af0cacd2aa..184a2afab7c 100644
--- a/code/modules/spells/spell_types/self/splattercasting_spell.dm
+++ b/code/modules/spells/spell_types/self/splattercasting_spell.dm
@@ -29,6 +29,7 @@
merely a vessel for the arcane flow. Soon, all that is left is not pain, but hunger."))
cast_on.set_species(/datum/species/vampire)
+ cast_on.blood_volume = BLOOD_VOLUME_NORMAL ///for predictable blood total amounts when the spell is first cast.
cast_on.AddComponent(/datum/component/splattercasting)
diff --git a/code/modules/surgery/bodyparts/wounds.dm b/code/modules/surgery/bodyparts/wounds.dm
index 1b50dbc8fd1..94c503614a2 100644
--- a/code/modules/surgery/bodyparts/wounds.dm
+++ b/code/modules/surgery/bodyparts/wounds.dm
@@ -85,7 +85,7 @@
// quick re-check to see if bare_wound_bonus applies, for the benefit of log_wound(), see about getting the check from check_woundings_mods() somehow
if(ishuman(owner))
var/mob/living/carbon/human/human_wearer = owner
- var/list/clothing = human_wearer.clothingonpart(src)
+ var/list/clothing = human_wearer.get_clothing_on_part(src)
for(var/obj/item/clothing/clothes_check as anything in clothing)
// unlike normal armor checks, we tabluate these piece-by-piece manually so we can also pass on appropriate damage the clothing's limbs if necessary
if(clothes_check.get_armor_rating(WOUND))
@@ -242,7 +242,7 @@
if(owner && ishuman(owner))
var/mob/living/carbon/human/human_owner = owner
- var/list/clothing = human_owner.clothingonpart(src)
+ var/list/clothing = human_owner.get_clothing_on_part(src)
for(var/obj/item/clothing/clothes as anything in clothing)
// unlike normal armor checks, we tabluate these piece-by-piece manually so we can also pass on appropriate damage the clothing's limbs if necessary
armor_ablation += clothes.get_armor_rating(WOUND)
diff --git a/code/modules/surgery/organs/_organ.dm b/code/modules/surgery/organs/_organ.dm
index 04103648fda..632e4c8b511 100644
--- a/code/modules/surgery/organs/_organ.dm
+++ b/code/modules/surgery/organs/_organ.dm
@@ -57,6 +57,8 @@
var/list/organ_traits
/// Status Effects that are given to the holder of the organ.
var/list/organ_effects
+ /// String displayed when the organ has decayed.
+ var/failing_desc = "has decayed for too long, and has turned a sickly color. It probably won't work without repairs."
// Players can look at prefs before atoms SS init, and without this
// they would not be able to see external organs, such as moth wings.
@@ -242,10 +244,7 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
. += span_notice("It should be inserted in the [parse_zone(zone)].")
if(organ_flags & ORGAN_FAILING)
- if(IS_ROBOTIC_ORGAN(src))
- . += span_warning("[src] seems to be broken.")
- return
- . += span_warning("[src] has decayed for too long, and has turned a sickly color. It probably won't work without repairs.")
+ . += span_warning("[src] [failing_desc]")
return
if(damage > high_threshold)
@@ -424,4 +423,4 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
/// Tries to replace the existing organ on the passed mob with this one, with special handling for replacing a brain without ghosting target
/obj/item/organ/proc/replace_into(mob/living/carbon/new_owner)
- Insert(new_owner, special = TRUE, drop_if_replaced = FALSE)
+ return Insert(new_owner, special = TRUE, drop_if_replaced = FALSE)
diff --git a/code/modules/surgery/organs/external/_external_organ.dm b/code/modules/surgery/organs/external/_external_organ.dm
index 54eb937e0ae..fd1af3d5f93 100644
--- a/code/modules/surgery/organs/external/_external_organ.dm
+++ b/code/modules/surgery/organs/external/_external_organ.dm
@@ -82,14 +82,13 @@
return
if(bodypart_overlay.imprint_on_next_insertion) //We only want this set *once*
-
- // SKYRAT EDIT - Customization - ORIGINAL: bodypart_overlay.set_appearance_from_name(receiver.dna.features[bodypart_overlay.feature_key])
- if(receiver.dna.features[bodypart_overlay.feature_key])
- bodypart_overlay.set_appearance_from_name(receiver.dna.features[bodypart_overlay.feature_key])
-
+ var/feature_name = receiver.dna.features[bodypart_overlay.feature_key]
+ if (isnull(feature_name))
+ bodypart_overlay.set_appearance_from_dna(receiver.dna) // SKYRAT EDIT CHANGE - ORIGINAL: feature_name = receiver.dna.species.external_organs[type]
+ // SKYRAT EDIT CHANGE START - Puts the following line in an else block
else
- bodypart_overlay.set_appearance_from_dna(receiver.dna)
- // SKYRAT EDIT END
+ bodypart_overlay.set_appearance_from_name(feature_name)
+ // SKYRAT EDIT CHANGE END
bodypart_overlay.imprint_on_next_insertion = FALSE
ownerlimb = limb
diff --git a/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm b/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm
index 0a7332c0dd8..f0578832969 100644
--- a/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm
+++ b/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm
@@ -4,6 +4,7 @@
desc = "A state-of-the-art implant that improves a baseline's functionality."
visual = FALSE
organ_flags = ORGAN_ROBOTIC
+ failing_desc = "seems to be broken."
var/implant_color = "#FFFFFF"
var/implant_overlay
diff --git a/code/modules/surgery/organs/internal/ears/_ears.dm b/code/modules/surgery/organs/internal/ears/_ears.dm
index 52f5d740520..b77efe90c2e 100644
--- a/code/modules/surgery/organs/internal/ears/_ears.dm
+++ b/code/modules/surgery/organs/internal/ears/_ears.dm
@@ -109,6 +109,7 @@
desc = "A basic cybernetic organ designed to mimic the operation of ears."
damage_multiplier = 0.9
organ_flags = ORGAN_ROBOTIC
+ failing_desc = "seems to be broken."
/obj/item/organ/internal/ears/cybernetic/upgraded
name = "cybernetic ears"
diff --git a/code/modules/surgery/organs/internal/eyes/_eyes.dm b/code/modules/surgery/organs/internal/eyes/_eyes.dm
index f2365c3988e..aca812a6186 100644
--- a/code/modules/surgery/organs/internal/eyes/_eyes.dm
+++ b/code/modules/surgery/organs/internal/eyes/_eyes.dm
@@ -318,6 +318,7 @@
icon_state = "cybernetic_eyeballs"
desc = "Your vision is augmented."
organ_flags = ORGAN_ROBOTIC
+ failing_desc = "seems to be broken."
/obj/item/organ/internal/eyes/robotic/emp_act(severity)
. = ..()
@@ -656,7 +657,7 @@
if(QDELETED(eye_owner) || !ishuman(eye_owner)) //Other carbon mobs don't have eye color.
return
-
+
if(!eye.on)
eye_icon_state = initial(eye_icon_state)
overlay_ignore_lighting = FALSE
diff --git a/code/modules/surgery/organs/internal/heart/_heart.dm b/code/modules/surgery/organs/internal/heart/_heart.dm
index ce4b948c653..e553f8f1307 100644
--- a/code/modules/surgery/organs/internal/heart/_heart.dm
+++ b/code/modules/surgery/organs/internal/heart/_heart.dm
@@ -203,6 +203,7 @@
base_icon_state = "heart-c"
organ_flags = ORGAN_ROBOTIC
maxHealth = STANDARD_ORGAN_THRESHOLD*0.75 //This also hits defib timer, so a bit higher than its less important counterparts
+ failing_desc = "seems to be broken."
var/dose_available = FALSE
var/rid = /datum/reagent/medicine/epinephrine
diff --git a/code/modules/surgery/organs/internal/liver/_liver.dm b/code/modules/surgery/organs/internal/liver/_liver.dm
index fe5ca01df4f..7baeb04b8b6 100644
--- a/code/modules/surgery/organs/internal/liver/_liver.dm
+++ b/code/modules/surgery/organs/internal/liver/_liver.dm
@@ -245,6 +245,7 @@
/obj/item/organ/internal/liver/cybernetic
name = "basic cybernetic liver"
desc = "A very basic device designed to mimic the functions of a human liver. Handles toxins slightly worse than an organic liver."
+ failing_desc = "seems to be broken."
icon_state = "liver-c"
organ_flags = ORGAN_ROBOTIC
maxHealth = STANDARD_ORGAN_THRESHOLD*0.5
diff --git a/code/modules/surgery/organs/internal/lungs/_lungs.dm b/code/modules/surgery/organs/internal/lungs/_lungs.dm
index 5e4e0648067..71dc305ac5f 100644
--- a/code/modules/surgery/organs/internal/lungs/_lungs.dm
+++ b/code/modules/surgery/organs/internal/lungs/_lungs.dm
@@ -837,6 +837,7 @@
/obj/item/organ/internal/lungs/cybernetic
name = "basic cybernetic lungs"
desc = "A basic cybernetic version of the lungs found in traditional humanoid entities."
+ failing_desc = "seems to be broken."
icon_state = "lungs-c"
organ_flags = ORGAN_ROBOTIC
maxHealth = STANDARD_ORGAN_THRESHOLD * 0.5
diff --git a/code/modules/surgery/organs/internal/stomach/_stomach.dm b/code/modules/surgery/organs/internal/stomach/_stomach.dm
index bebeaacf110..e7d22a3ece6 100644
--- a/code/modules/surgery/organs/internal/stomach/_stomach.dm
+++ b/code/modules/surgery/organs/internal/stomach/_stomach.dm
@@ -289,6 +289,7 @@
/obj/item/organ/internal/stomach/cybernetic
name = "basic cybernetic stomach"
desc = "A basic device designed to mimic the functions of a human stomach"
+ failing_desc = "seems to be broken."
icon_state = "stomach-c"
organ_flags = ORGAN_ROBOTIC
maxHealth = STANDARD_ORGAN_THRESHOLD * 0.5
diff --git a/code/modules/surgery/organs/internal/stomach/stomach_ethereal.dm b/code/modules/surgery/organs/internal/stomach/stomach_ethereal.dm
index 4d43b6a3a0a..4cc8ee404c1 100644
--- a/code/modules/surgery/organs/internal/stomach/stomach_ethereal.dm
+++ b/code/modules/surgery/organs/internal/stomach/stomach_ethereal.dm
@@ -92,7 +92,7 @@
playsound(carbon, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5)
carbon.cut_overlay(overcharge)
- tesla_zap(carbon, 2, crystal_charge*2.5, ZAP_OBJ_DAMAGE | ZAP_LOW_POWER_GEN | ZAP_ALLOW_DUPLICATES)
+ tesla_zap(carbon, 2, crystal_charge * 1e3, ZAP_OBJ_DAMAGE | ZAP_LOW_POWER_GEN | ZAP_ALLOW_DUPLICATES)
adjust_charge(ETHEREAL_CHARGE_FULL - crystal_charge)
carbon.visible_message(span_danger("[carbon] violently discharges energy!"), span_warning("You violently discharge energy!"))
diff --git a/code/modules/surgery/organs/internal/tongue/_tongue.dm b/code/modules/surgery/organs/internal/tongue/_tongue.dm
index e9c47a0f237..08ee3d20faf 100644
--- a/code/modules/surgery/organs/internal/tongue/_tongue.dm
+++ b/code/modules/surgery/organs/internal/tongue/_tongue.dm
@@ -190,7 +190,7 @@
languages_native = list(/datum/language/draconic, /datum/language/ashtongue) //SKYRAT EDIT: Ashtongue for Ashwalkers
liked_foodtypes = GORE | MEAT | SEAFOOD | NUTS | BUGS
disliked_foodtypes = GRAIN | DAIRY | CLOTH | GROSS
-
+ voice_filter = @{"[0:a] asplit [out0][out2]; [out0] asetrate=%SAMPLE_RATE%*0.9,aresample=%SAMPLE_RATE%,atempo=1/0.9,aformat=channel_layouts=mono,volume=0.2 [p0]; [out2] asetrate=%SAMPLE_RATE%*1.1,aresample=%SAMPLE_RATE%,atempo=1/1.1,aformat=channel_layouts=mono,volume=0.2[p2]; [p0][0][p2] amix=inputs=3"}
/obj/item/organ/internal/tongue/lizard/modify_speech(datum/source, list/speech_args)
var/static/regex/lizard_hiss = new("s+", "g")
var/static/regex/lizard_hiSS = new("S+", "g")
@@ -499,7 +499,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list())
say_mod = "hisses"
taste_sensitivity = 10 // LIZARDS ARE ALIENS CONFIRMED
modifies_speech = TRUE // not really, they just hiss
-
+ voice_filter = @{"[0:a] asplit [out0][out2]; [out0] asetrate=%SAMPLE_RATE%*0.8,aresample=%SAMPLE_RATE%,atempo=1/0.8,aformat=channel_layouts=mono [p0]; [out2] asetrate=%SAMPLE_RATE%*1.2,aresample=%SAMPLE_RATE%,atempo=1/1.2,aformat=channel_layouts=mono[p2]; [p0][0][p2] amix=inputs=3"}
// Aliens can only speak alien and a few other languages.
/obj/item/organ/internal/tongue/alien/get_possible_languages()
return list(
@@ -560,6 +560,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list())
/obj/item/organ/internal/tongue/robot
name = "robotic voicebox"
desc = "A voice synthesizer that can interface with organic lifeforms."
+ failing_desc = "seems to be broken."
organ_flags = ORGAN_ROBOTIC
icon_state = "tonguerobot"
say_mod = "states"
@@ -607,6 +608,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list())
toxic_foodtypes = NONE //no food is particularly toxic to ethereals
attack_verb_continuous = list("shocks", "jolts", "zaps")
attack_verb_simple = list("shock", "jolt", "zap")
+ voice_filter = @{"[0:a] asplit [out0][out2]; [out0] asetrate=%SAMPLE_RATE%*0.99,aresample=%SAMPLE_RATE%,volume=0.3 [p0]; [p0][out2] amix=inputs=2"}
// Ethereal tongues can speak all default + voltaic
/obj/item/organ/internal/tongue/ethereal/get_possible_languages()
diff --git a/code/modules/surgery/plastic_surgery.dm b/code/modules/surgery/plastic_surgery.dm
index 440d48d1c5e..424251143c3 100644
--- a/code/modules/surgery/plastic_surgery.dm
+++ b/code/modules/surgery/plastic_surgery.dm
@@ -1,3 +1,9 @@
+/// Disk containing info for doing advanced plastic surgery. Spawns in maint and available as a role-restricted item in traitor uplinks.
+/obj/item/disk/surgery/advanced_plastic_surgery
+ name = "Advanced Plastic Surgery Disk"
+ desc = "The disk provides instructions on how to do an Advanced Plastic Surgery, this surgery allows one-self to completely remake someone's face with that of another. Provided they have a picture of them in their offhand when reshaping the face. With the surgery long becoming obsolete with the rise of genetics technology. This item became an antique to many collectors, With only the cheaper and easier basic form of plastic surgery remaining in use in most places."
+ surgeries = list(/datum/surgery/plastic_surgery/advanced)
+
/datum/surgery/plastic_surgery
name = "Plastic surgery"
surgery_flags = SURGERY_REQUIRE_RESTING | SURGERY_REQUIRE_LIMB | SURGERY_REQUIRES_REAL_LIMB | SURGERY_MORBID_CURIOSITY
@@ -9,6 +15,41 @@
/datum/surgery_step/close,
)
+/datum/surgery/plastic_surgery/advanced
+ name = "advanced plastic surgery"
+ steps = list(
+ /datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/insert_plastic,
+ /datum/surgery_step/reshape_face,
+ /datum/surgery_step/close,
+ )
+
+//Insert plastic step, It ain't called plastic surgery for nothing! :)
+/datum/surgery_step/insert_plastic
+ name = "insert plastic (plastic)"
+ implements = list(
+ /obj/item/stack/sheet/plastic = 100,
+ /obj/item/stack/sheet/meat = 100)
+ time = 3.2 SECONDS
+ preop_sound = 'sound/effects/blobattack.ogg'
+ success_sound = 'sound/effects/attackblob.ogg'
+ failure_sound = 'sound/effects/blobattack.ogg'
+
+/datum/surgery_step/insert_plastic/preop(mob/user, mob/living/target, target_zone, obj/item/stack/tool, datum/surgery/surgery)
+ display_results(
+ user,
+ target,
+ span_notice("You begin to insert [tool] into the incision in [target]'s [parse_zone(target_zone)]..."),
+ span_notice("[user] begins to insert [tool] into the incision in [target]'s [parse_zone(target_zone)]."),
+ span_notice("[user] begins to insert [tool] into the incision in [target]'s [parse_zone(target_zone)]."),
+ )
+ display_pain(target, "You feel something inserting just below the skin in your [parse_zone(target_zone)].")
+
+/datum/surgery_step/insert_plastic/success(mob/user, mob/living/target, target_zone, obj/item/stack/tool, datum/surgery/surgery, default_display_results)
+ . = ..()
+ tool.use(1)
+
//reshape_face
/datum/surgery_step/reshape_face
name = "reshape face (scalpel)"
@@ -43,8 +84,15 @@
else
var/list/names = list()
if(!isabductor(user))
- for(var/i in 1 to 10)
- names += target.dna.species.random_name(target.gender, TRUE)
+ var/obj/item/offhand = user.get_inactive_held_item()
+ if(istype(offhand, /obj/item/photo) && istype(surgery, /datum/surgery/plastic_surgery/advanced))
+ var/obj/item/photo/disguises = offhand
+ for(var/namelist as anything in disguises.picture?.names_seen)
+ names += namelist
+ else
+ user.visible_message(span_warning("You have no picture to base the appearance on, reverting to random appearances."))
+ for(var/i in 1 to 10)
+ names += target.dna.species.random_name(target.gender, TRUE)
else
for(var/_i in 1 to 9)
names += "Subject [target.gender == MALE ? "i" : "o"]-[pick("a", "b", "c", "d", "e")]-[rand(10000, 99999)]"
diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm
index 49fbecc2271..c5f62883b5f 100644
--- a/code/modules/surgery/tools.dm
+++ b/code/modules/surgery/tools.dm
@@ -259,6 +259,12 @@
butcher_sound = 'sound/weapons/circsawhit.ogg', \
)
//saws are very accurate and fast at butchering
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/chainsaw)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
/obj/item/circular_saw/get_surgery_tool_overlay(tray_extended)
return surgical_tray_overlay
diff --git a/code/modules/unit_tests/greyscale_config.dm b/code/modules/unit_tests/greyscale_config.dm
index 9c5106be5b0..d3d9ce9d4fd 100644
--- a/code/modules/unit_tests/greyscale_config.dm
+++ b/code/modules/unit_tests/greyscale_config.dm
@@ -38,4 +38,4 @@
continue
var/number_of_colors = length(colors) - 1
if(config.expected_colors != number_of_colors)
- TEST_FAIL("[thing] has the wrong amount of colors configured for [config.DebugName()]. Expected [config.expected_colors] but only found [number_of_colors].")
+ TEST_FAIL("[thing] has the wrong amount of colors configured for [config.DebugName()]. Expected [config.expected_colors] colors but found [number_of_colors].")
diff --git a/code/modules/unit_tests/simple_animal_freeze.dm b/code/modules/unit_tests/simple_animal_freeze.dm
index 8de11513eaa..3c97dfe2773 100644
--- a/code/modules/unit_tests/simple_animal_freeze.dm
+++ b/code/modules/unit_tests/simple_animal_freeze.dm
@@ -64,22 +64,10 @@
/mob/living/simple_animal/hostile/asteroid/gutlunch/grublunch,
/mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck,
/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen,
- /mob/living/simple_animal/hostile/asteroid/hivelord,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/advanced,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/dwarf,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/portal,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril,
- /mob/living/simple_animal/hostile/asteroid/hivelordbrood,
- /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion,
- /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/advanced,
- /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/snow,
/mob/living/simple_animal/hostile/asteroid/ice_demon,
/mob/living/simple_animal/hostile/asteroid/polarbear,
/mob/living/simple_animal/hostile/asteroid/polarbear/lesser,
/mob/living/simple_animal/hostile/asteroid/wolf,
- /mob/living/simple_animal/hostile/big_legion,
/mob/living/simple_animal/hostile/blob,
/mob/living/simple_animal/hostile/blob/blobbernaut,
/mob/living/simple_animal/hostile/blob/blobbernaut/independent,
@@ -181,7 +169,6 @@
/mob/living/simple_animal/hostile/retaliate/goose/vomit,
/mob/living/simple_animal/hostile/retaliate/nanotrasenpeace,
/mob/living/simple_animal/hostile/retaliate/nanotrasenpeace/ranged,
- /mob/living/simple_animal/hostile/retaliate/snake,
/mob/living/simple_animal/hostile/retaliate/trader,
/mob/living/simple_animal/hostile/retaliate/trader/mrbones,
/mob/living/simple_animal/hostile/skeleton,
@@ -215,7 +202,6 @@
/mob/living/simple_animal/pet/gondola,
/mob/living/simple_animal/pet/gondola/gondolapod,
/mob/living/simple_animal/revenant,
- /mob/living/simple_animal/robot_customer,
/mob/living/simple_animal/shade,
/mob/living/simple_animal/slime,
/mob/living/simple_animal/slime/pet,
diff --git a/code/modules/uplink/uplink_items/implant.dm b/code/modules/uplink/uplink_items/implant.dm
index 34fc9eedb0f..87c9fd6c96c 100644
--- a/code/modules/uplink/uplink_items/implant.dm
+++ b/code/modules/uplink/uplink_items/implant.dm
@@ -9,11 +9,14 @@
/datum/uplink_item/implants/freedom
name = "Freedom Implant"
- desc = "An implant injected into the body and later activated at the user's will. It will attempt to free the \
- user from common restraints such as handcuffs."
+ desc = "Can be activated to release common restraints such as handcuffs, legcuffs, and even bolas tethered around the legs."
item = /obj/item/storage/box/syndie_kit/imp_freedom
cost = 5
+/datum/uplink_item/implants/freedom/New()
+ . = ..()
+ desc += " Implant has enough energy for [FREEDOM_IMPLANT_CHARGES] uses before it becomes inert and harmlessly self-destructs."
+
/datum/uplink_item/implants/radio
name = "Internal Syndicate Radio Implant"
desc = "An implant injected into the body, allowing the use of an internal Syndicate radio. \
diff --git a/code/modules/uplink/uplink_items/job.dm b/code/modules/uplink/uplink_items/job.dm
index b971e07619c..e585b07bb5f 100644
--- a/code/modules/uplink/uplink_items/job.dm
+++ b/code/modules/uplink/uplink_items/job.dm
@@ -173,6 +173,16 @@
cost = 5
surplus = 50
+/datum/uplink_item/role_restricted/advanced_plastic_surgery
+ name = "Advanced Plastic Surgery Program"
+ desc = "A bootleg copy of an collector item, this disk contains the procedure to perform advanced plastic surgery, allowing you to model someone's face and voice based on a picture taken by a camera on your offhand. \
+ All changes are superficial and does not change ones genetic makeup. \
+ Insert into an Operating Console to enable the procedure."
+ item = /obj/item/disk/surgery/brainwashing
+ restricted_roles = list(JOB_MEDICAL_DOCTOR, JOB_CHIEF_MEDICAL_OFFICER, JOB_ROBOTICIST)
+ cost = 1
+ surplus = 50
+
/datum/uplink_item/role_restricted/springlock_module
name = "Heavily Modified Springlock MODsuit Module"
desc = "A module that spans the entire size of the MOD unit, sitting under the outer shell. \
diff --git a/code/modules/uplink/uplink_items/stealthy.dm b/code/modules/uplink/uplink_items/stealthy.dm
index 54c9bbe9adc..491f8e8e99d 100644
--- a/code/modules/uplink/uplink_items/stealthy.dm
+++ b/code/modules/uplink/uplink_items/stealthy.dm
@@ -90,7 +90,16 @@
slur as if inebriated. It can produce an infinite number \
of bolts, but takes time to automatically recharge after each shot."
item = /obj/item/gun/energy/recharge/ebow
- progression_minimum = 30 MINUTES
cost = 10
surplus = 50
purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS)
+
+/datum/uplink_item/stealthy_weapons/contrabaton
+ name = "Contractor Baton"
+ desc = "A compact, specialised baton assigned to Syndicate contractors. Applies light electrical shocks to targets. \
+ These shocks are capable of affecting the inner circuitry of most robots as well, applying a short stun. \
+ Has the added benefit of affecting the vocal cords of your victim, causing them to slur as if inebriated."
+ item = /obj/item/melee/baton/telescopic/contractor_baton
+ cost = 12
+ surplus = 50
+ purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS)
diff --git a/code/modules/vending/wardrobes.dm b/code/modules/vending/wardrobes.dm
index da2c08e04c9..2a5360c1ed2 100644
--- a/code/modules/vending/wardrobes.dm
+++ b/code/modules/vending/wardrobes.dm
@@ -61,6 +61,7 @@
/obj/item/clothing/head/utility/surgerycap/green = 4,
/obj/item/clothing/head/beret/medical/paramedic = 4,
/obj/item/clothing/head/soft/paramedic = 4,
+ /obj/item/clothing/head/utility/head_mirror = 4,
/obj/item/clothing/mask/bandana/striped/medical = 4,
/obj/item/clothing/mask/surgical = 4,
/obj/item/clothing/under/rank/medical/doctor = 4,
diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm
index 9d3a298812e..4258dc5a304 100644
--- a/code/modules/zombie/items.dm
+++ b/code/modules/zombie/items.dm
@@ -11,20 +11,24 @@
bare_wound_bonus = 15
sharpness = SHARP_EDGED
-/obj/item/mutant_hand/zombie/afterattack(atom/target, mob/user, proximity_flag)
+/obj/item/mutant_hand/zombie/afterattack(atom/target, mob/living/user, proximity_flag)
. = ..()
if(!proximity_flag)
return
else if(isliving(target))
if(ishuman(target))
- try_to_zombie_infect(target)
+ try_to_zombie_infect(target, user, user.zone_selected)
else
. |= AFTERATTACK_PROCESSED_ITEM
check_feast(target, user)
-/proc/try_to_zombie_infect(mob/living/carbon/human/target)
+/proc/try_to_zombie_infect(mob/living/carbon/human/target, mob/living/user, def_zone = BODY_ZONE_CHEST)
CHECK_DNA_AND_SPECIES(target)
+ // Can't zombify with no head
+ if(!target.get_bodypart(BODY_ZONE_HEAD))
+ return
+
if(HAS_TRAIT(target, TRAIT_NO_ZOMBIFY))
// cannot infect any TRAIT_NO_ZOMBIFY human
return
@@ -33,11 +37,31 @@
if(HAS_TRAIT(target, TRAIT_VIRUS_RESISTANCE) && prob(75))
return
+ var/obj/item/bodypart/actual_limb = target.get_bodypart(def_zone)
+
+ // What you hitting bro?
+ if(!actual_limb)
+ return
+
+ var/limb_damage = actual_limb.get_damage()
+ var/limb_armor = max(0, target.getarmor(actual_limb, BIO) - 25)
+
+ // This is a pretty jank way to do this, but in short:
+ // if they have thick material on that bodypart it will always need at least 25 previous limb damage to trigger an infection.
+ // and if their bio armor isn't thick it's a bit weaker.
+ for(var/obj/item/clothing/iter_clothing in target.get_clothing_on_part(actual_limb))
+ if(iter_clothing.clothing_flags & THICKMATERIAL)
+ limb_armor += 25
+
+ if(limb_armor > limb_damage)
+ return
+
var/obj/item/organ/internal/zombie_infection/infection
infection = target.get_organ_slot(ORGAN_SLOT_ZOMBIE)
if(!infection)
infection = new()
infection.Insert(target)
+ to_chat(user, span_alien("You see [target] twitch for a moment as [target.p_their()] head is covered in \a [infection] - [target.p_Theyve()] been infected."))
/obj/item/mutant_hand/zombie/suicide_act(mob/living/user)
user.visible_message(span_suicide("[user] is ripping [user.p_their()] brains out! It looks like [user.p_theyre()] trying to commit suicide!"))
diff --git a/icons/mob/clothing/head/pai_head.dmi b/icons/mob/clothing/head/pai_head.dmi
index 0a04e7e8ab2..e5dd4965d8b 100644
Binary files a/icons/mob/clothing/head/pai_head.dmi and b/icons/mob/clothing/head/pai_head.dmi differ
diff --git a/icons/mob/clothing/head/utility.dmi b/icons/mob/clothing/head/utility.dmi
index 3f3a668181c..ada1b90c4b0 100644
Binary files a/icons/mob/clothing/head/utility.dmi and b/icons/mob/clothing/head/utility.dmi differ
diff --git a/icons/mob/huds/hud.dmi b/icons/mob/huds/hud.dmi
index ec9be118f57..9a602eeb806 100644
Binary files a/icons/mob/huds/hud.dmi and b/icons/mob/huds/hud.dmi differ
diff --git a/icons/mob/silicon/pai.dmi b/icons/mob/silicon/pai.dmi
index 624ed669519..2be986d411d 100644
Binary files a/icons/mob/silicon/pai.dmi and b/icons/mob/silicon/pai.dmi differ
diff --git a/icons/mob/simple/lavaland/lavaland_monsters.dmi b/icons/mob/simple/lavaland/lavaland_monsters.dmi
index 13c37dca594..38b78cf468f 100644
Binary files a/icons/mob/simple/lavaland/lavaland_monsters.dmi and b/icons/mob/simple/lavaland/lavaland_monsters.dmi differ
diff --git a/icons/mob/telegraphing/telegraph.dmi b/icons/mob/telegraphing/telegraph.dmi
index d5e03419cd8..de525ead4ee 100644
Binary files a/icons/mob/telegraphing/telegraph.dmi and b/icons/mob/telegraphing/telegraph.dmi differ
diff --git a/icons/obj/clothing/head/utility.dmi b/icons/obj/clothing/head/utility.dmi
index 9571b2add78..17040f5bb8b 100644
Binary files a/icons/obj/clothing/head/utility.dmi and b/icons/obj/clothing/head/utility.dmi differ
diff --git a/icons/obj/exploration.dmi b/icons/obj/exploration.dmi
index 2f9d004bee2..b7224d2df84 100644
Binary files a/icons/obj/exploration.dmi and b/icons/obj/exploration.dmi differ
diff --git a/icons/obj/medical/organs/mining_organs.dmi b/icons/obj/medical/organs/mining_organs.dmi
index f3fc298284b..172f94001ff 100644
Binary files a/icons/obj/medical/organs/mining_organs.dmi and b/icons/obj/medical/organs/mining_organs.dmi differ
diff --git a/modular_skyrat/master_files/code/datums/traits/good.dm b/modular_skyrat/master_files/code/datums/traits/good.dm
index 22987f7705d..08f265145a9 100644
--- a/modular_skyrat/master_files/code/datums/traits/good.dm
+++ b/modular_skyrat/master_files/code/datums/traits/good.dm
@@ -68,6 +68,16 @@
right_arm.unarmed_miss_sound = initial(right_arm.unarmed_miss_sound)
right_arm.unarmed_sharpness = initial(right_arm.unarmed_sharpness)
+/datum/quirk/water_breathing
+ name = "Water breathing"
+ desc = "You are able to breathe underwater!"
+ value = 2
+ mob_trait = TRAIT_WATER_BREATHING
+ gain_text = span_notice("You become acutely aware of the moisture in your lungs and in the air. It feels nice.")
+ lose_text = span_danger("You suddenly realize the moisture in your lungs feels really weird, and you almost choke on it!")
+ medical_record_text = "Patient possesses biology compatible with aquatic respiration."
+ icon = FA_ICON_FISH
+
// AdditionalEmotes *turf quirks
/datum/quirk/water_aspect
name = "Water aspect (Emotes)"
diff --git a/modular_skyrat/master_files/code/modules/mob/living/human/species.dm b/modular_skyrat/master_files/code/modules/mob/living/human/species.dm
index b2b9eaeecba..30df82a7f11 100644
--- a/modular_skyrat/master_files/code/modules/mob/living/human/species.dm
+++ b/modular_skyrat/master_files/code/modules/mob/living/human/species.dm
@@ -32,3 +32,14 @@
/datum/species/proc/apply_supplementary_body_changes(mob/living/carbon/human/target, datum/preferences/preferences, visuals_only = FALSE)
return
+
+/datum/species/create_pref_traits_perks()
+ . = ..()
+
+ if (TRAIT_WATER_BREATHING in inherent_traits)
+ . += list(list(
+ SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK,
+ SPECIES_PERK_ICON = FA_ICON_FISH,
+ SPECIES_PERK_NAME = "Waterbreathing",
+ SPECIES_PERK_DESC = "[plural_form] can breathe in water, making pools a lot safer to be in!",
+ ))
diff --git a/modular_skyrat/modules/alerts/code/default_announcer.dm b/modular_skyrat/modules/alerts/code/default_announcer.dm
index 7ae320f01f8..86add70db58 100644
--- a/modular_skyrat/modules/alerts/code/default_announcer.dm
+++ b/modular_skyrat/modules/alerts/code/default_announcer.dm
@@ -43,7 +43,6 @@
ANNOUNCER_KLAXON = 'modular_skyrat/modules/black_mesa/sound/siren1_long.ogg',
ANNOUNCER_ICARUS = 'modular_skyrat/modules/assault_operatives/sound/icarus_alarm.ogg',
ANNOUNCER_NRI_RAIDERS = 'modular_skyrat/modules/encounters/sounds/morse.ogg',
- ANNOUNCER_FUNGI = 'modular_skyrat/modules/alerts/sound/alerts/fungi.ogg',
ANNOUNCER_DEPARTMENTAL = 'modular_skyrat/modules/alerts/sound/alerts/alert3.ogg',
ANNOUNCER_SHUTTLE = 'modular_skyrat/modules/alerts/sound/alerts/alert3.ogg',
)
diff --git a/modular_skyrat/modules/alerts/sound/alerts/fungi.ogg b/modular_skyrat/modules/alerts/sound/alerts/fungi.ogg
deleted file mode 100644
index 7eb45de94a2..00000000000
Binary files a/modular_skyrat/modules/alerts/sound/alerts/fungi.ogg and /dev/null differ
diff --git a/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm b/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm
index e34a414cf8e..ba1dd931c3a 100644
--- a/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm
+++ b/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm
@@ -173,7 +173,7 @@
. = ..()
var/mob_type = pick(
/mob/living/basic/mining/goliath,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion,
+ /mob/living/basic/mining/legion,
/mob/living/basic/mining/brimdemon,
/mob/living/basic/mining/watcher,
/mob/living/basic/mining/lobstrosity/lava,
@@ -373,5 +373,5 @@
find_animal.faction = list(FACTION_ASHWALKER)
- find_animal.revive()
+ find_animal.revive(HEAL_ALL)
return TRUE
diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/deforest_medical.dm b/modular_skyrat/modules/company_imports/code/armament_datums/deforest_medical.dm
index 3f9b9b73b28..40f8ef775f7 100644
--- a/modular_skyrat/modules/company_imports/code/armament_datums/deforest_medical.dm
+++ b/modular_skyrat/modules/company_imports/code/armament_datums/deforest_medical.dm
@@ -121,7 +121,7 @@
cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/deforest/equipment/surgical_tools
- item_type = /obj/item/storage/backpack/duffelbag/med/surgery
+ item_type = /obj/item/surgery_tray/full
cost = PAYCHECK_COMMAND
/datum/armament_entry/company_import/deforest/equipment/advanced_health_analyer
diff --git a/modular_skyrat/modules/customization/game/objects/items/plushes.dm b/modular_skyrat/modules/customization/game/objects/items/plushes.dm
index d718d409b49..1d2992cf8ef 100644
--- a/modular_skyrat/modules/customization/game/objects/items/plushes.dm
+++ b/modular_skyrat/modules/customization/game/objects/items/plushes.dm
@@ -467,7 +467,7 @@
gender = FEMALE
attack_verb_continuous = list("pats", "hugs", "scolds", "pets")
attack_verb_simple = list("pat", "hug", "scold", "pet")
- squeak_override = list('sound/effects/mousesqueek.ogg' = 1, 'modular_skyrat/modules/emotes/sound/voice/mothsqueak.ogg' = 1,)
+ squeak_override = list('sound/creatures/mousesqueek.ogg' = 1, 'modular_skyrat/modules/emotes/sound/voice/mothsqueak.ogg' = 1,)
responses = list("Rabbits are prey animals and are therefore constantly aware of their surroundings.", "Things to jump up on (they like to be in high places)", "become a rabbit today!", "Be cunning and full of tricks...", "Subscription confirmed! Thank you for choosing RABBITFACTS +TM+!", "Holland Lops are a breed of rabbit originating in the Netherlands.", "Rabbits may need medication to keep themselves healthy, and that's ok! Make sure to take yours too!", "rabbits really liked this product", "A healthy rabbit diet includes fresh vegetables.", "Rabbits do not hibernate. Their schedules are much too busy.", "the rate of bunnies is measured by RPB (rabbits per bunny)", )
/obj/item/toy/plush/skyrat/chunko/andrew
@@ -477,7 +477,7 @@
gender = MALE
attack_verb_continuous = list("pats", "hugs", "scolds", "pets")
attack_verb_simple = list("pat", "hug", "scold", "pet")
- squeak_override = list('sound/effects/mousesqueek.ogg' = 1, 'modular_skyrat/modules/emotes/sound/voice/mothsqueak.ogg' = 1,)
+ squeak_override = list('sound/creatures/mousesqueek.ogg' = 1, 'modular_skyrat/modules/emotes/sound/voice/mothsqueak.ogg' = 1,)
// All lowercase messages are intentional
responses = list("bunny who you best pray you never encounter, lest you suffer a fate worse than death.", "this is a bunny!", "I wonder what would happen if you took bunnies, and combined them with rabbits, and merged their properties and characteristics. It's something to think about.", "If you're cold, they're cold. Give them the deed to your house.", "bunny that goes yeah! woo! yeah! woo! yeah! woo! yeah! woo! yeah! woo! yeah!", "the bunnies are beyond my comprehension", "it's a bunny thing, you wouldn't get it", "this bunny has an unfathomable power level", "%pull the string and I'll bink at you...I'm your bunny.", "Bunny (1954)", "the bunny that pulls the strings....", )
diff --git a/modular_skyrat/modules/customization/modules/clothing/~donator/donator_clothing.dm b/modular_skyrat/modules/customization/modules/clothing/~donator/donator_clothing.dm
index 64a6c5c1339..746380b59cb 100644
--- a/modular_skyrat/modules/customization/modules/clothing/~donator/donator_clothing.dm
+++ b/modular_skyrat/modules/customization/modules/clothing/~donator/donator_clothing.dm
@@ -936,7 +936,8 @@
/obj/item/clothing/glasses/welding/steampunk_goggles/attackby(obj/item/attacking_item, mob/living/user, params)
if(!istype(attacking_item, /obj/item/clothing/glasses/welding))
- ..()
+ return ..()
+
if(welding_upgraded)
to_chat(user, span_warning("\The [src] was already upgraded to have welding protection!"))
return
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm
index 3d0aaf94db5..76ebf34b682 100644
--- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm
+++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm
@@ -149,7 +149,7 @@ GLOBAL_LIST_EMPTY(customizable_races)
var/datum/sprite_accessory/undershirt/undershirt = GLOB.undershirt_list[species_human.undershirt]
if(undershirt)
var/mutable_appearance/undershirt_overlay
- if(species_human.dna.species.sexes && species_human.gender == FEMALE)
+ if(species_human.dna.species.sexes && species_human.physique == FEMALE)
undershirt_overlay = wear_female_version(undershirt.icon_state, undershirt.icon, BODY_LAYER)
else
undershirt_overlay = mutable_appearance(undershirt.icon, undershirt.icon_state, -BODY_LAYER)
diff --git a/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/other_reagents.dm b/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/other_reagents.dm
index fabba52db0f..1c03bbf2ca3 100644
--- a/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -70,3 +70,30 @@
else
to_chat(M, span_notice("[pick("I feel oddly calm.", "I feel relaxed.", "Mew?")]"))
..()
+
+#define DERMAGEN_SCAR_FIX_AMOUNT 10
+
+/datum/reagent/medicine/dermagen
+ name = "Dermagen"
+ description = "Heals scars formed by past physical trauma when applied. Minimum 10u needed, only works when applied topically."
+ reagent_state = LIQUID
+ color = "#FFEBEB"
+ ph = 6
+ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
+
+/datum/reagent/medicine/dermagen/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE)
+ . = ..()
+ if(!iscarbon(exposed_mob))
+ return
+ if(!(methods & (PATCH|TOUCH|VAPOR)))
+ return
+ var/mob/living/carbon/scarred = exposed_mob
+ if(scarred.stat == DEAD)
+ show_message = FALSE
+ if(show_message)
+ to_chat(scarred, span_danger("The scars on your body start to fade and disappear."))
+ if(reac_volume >= DERMAGEN_SCAR_FIX_AMOUNT)
+ for(var/i in scarred.all_scars)
+ qdel(i)
+
+#undef DERMAGEN_SCAR_FIX_AMOUNT
diff --git a/modular_skyrat/modules/customization/modules/reagents/chemistry/recipes/medicine.dm b/modular_skyrat/modules/customization/modules/reagents/chemistry/recipes/medicine.dm
index afcfa2da8cd..34b97214bb8 100644
--- a/modular_skyrat/modules/customization/modules/reagents/chemistry/recipes/medicine.dm
+++ b/modular_skyrat/modules/customization/modules/reagents/chemistry/recipes/medicine.dm
@@ -24,3 +24,8 @@
results = list(/datum/reagent/medicine/taste_suppressor = 3, /datum/reagent/chlorine = 1) // The chlorine dissociated from the sodium to allow for the synthesis of the taste suppressor
required_reagents = list(/datum/reagent/consumable/salt = 2, /datum/reagent/sulfur = 1, /datum/reagent/water = 1)
required_temp = 300
+
+/datum/chemical_reaction/medicine/dermagen
+ results = list(/datum/reagent/medicine/dermagen = 5)
+ required_reagents = list(/datum/reagent/consumable/ethanol = 4, /datum/reagent/medicine/c2/synthflesh = 3, /datum/reagent/medicine/mine_salve = 3)
+ mix_message = "The slurry congeals into a thick cream."
diff --git a/modular_skyrat/modules/decay_subsystem/code/nests.dm b/modular_skyrat/modules/decay_subsystem/code/nests.dm
index 3a8dad43888..74424371e87 100644
--- a/modular_skyrat/modules/decay_subsystem/code/nests.dm
+++ b/modular_skyrat/modules/decay_subsystem/code/nests.dm
@@ -200,7 +200,7 @@
desc = "These pulsating eggs are oozing out a puss like substance..."
icon_state = "nest_eggs"
light_color = LIGHT_COLOR_BRIGHT_YELLOW
- monster_types = list(/mob/living/simple_animal/hostile/retaliate/snake)
+ monster_types = list(/mob/living/basic/snake)
max_mobs = 8
spawn_cooldown = 5 SECONDS
diff --git a/modular_skyrat/modules/emotes/code/emotes.dm b/modular_skyrat/modules/emotes/code/emotes.dm
index 5f41b22751b..16c8ecbcef6 100644
--- a/modular_skyrat/modules/emotes/code/emotes.dm
+++ b/modular_skyrat/modules/emotes/code/emotes.dm
@@ -143,7 +143,7 @@
message = "squeaks!"
emote_type = EMOTE_AUDIBLE
vary = TRUE
- sound = 'sound/effects/mousesqueek.ogg'
+ sound = 'sound/creatures/mousesqueek.ogg'
/datum/emote/living/merp
key = "merp"
diff --git a/modular_skyrat/modules/faction/code/outfit.dm b/modular_skyrat/modules/faction/code/outfit.dm
index 4728353e4ec..a808f58c05f 100644
--- a/modular_skyrat/modules/faction/code/outfit.dm
+++ b/modular_skyrat/modules/faction/code/outfit.dm
@@ -43,7 +43,7 @@
back = /obj/item/storage/backpack
id = /obj/item/card/id/faction_crew
l_pocket = /obj/item/melee/energy/sword
- l_hand = /obj/item/storage/backpack/duffelbag/med/surgery
+ l_hand = /obj/item/surgery_tray/full
backpack_contents = list(/obj/item/storage/box/survival/engineer=1, /obj/item/storage/medkit/tactical=1,/obj/item/storage/medkit/regular=1,/obj/item/storage/medkit/toxin=1, /obj/item/ammo_box/magazine/m45=2, /obj/item/gun/ballistic/automatic/pistol/m1911=1,/obj/item/healthanalyzer=1,/obj/item/stack/spacecash/c1000=1)
/datum/outfit/faction_tech
diff --git a/modular_skyrat/modules/fauna_reagent/fauna_reagent.dm b/modular_skyrat/modules/fauna_reagent/fauna_reagent.dm
index cee0e7efab5..796dbef0daf 100644
--- a/modular_skyrat/modules/fauna_reagent/fauna_reagent.dm
+++ b/modular_skyrat/modules/fauna_reagent/fauna_reagent.dm
@@ -15,14 +15,57 @@
/mob/living/simple_animal/Life(seconds_per_tick, times_fired)
. = ..()
- if(reagent_health && reagents)
- for(var/datum/reagent/reagents_within as anything in reagents.reagent_list)
- if(istype(reagents_within, /datum/reagent/toxin))
- var/datum/reagent/toxin/toxin_reagent = reagents_within
- var/toxin_damage = round(toxin_reagent.toxpwr)
- adjustHealth(toxin_damage + 1)
- reagents.remove_reagent(toxin_reagent.type, 0.5)
- continue
- if(istype(reagents_within, /datum/reagent/medicine))
- adjustHealth(-1)
- reagents.remove_reagent(reagents_within.type, 0.5)
+
+ if(!reagent_health)
+ return
+
+ if(!reagents)
+ return
+
+ if(stat == DEAD)
+ return
+
+ for(var/datum/reagent/reagents_within as anything in reagents.reagent_list)
+ if(istype(reagents_within, /datum/reagent/toxin))
+ var/datum/reagent/toxin/toxin_reagent = reagents_within
+ var/toxin_damage = round(toxin_reagent.toxpwr)
+ adjustHealth(toxin_damage + 1)
+ reagents.remove_reagent(toxin_reagent.type, 0.5)
+ continue
+
+ if(istype(reagents_within, /datum/reagent/medicine))
+ adjustHealth(-1)
+ reagents.remove_reagent(reagents_within.type, 0.5)
+
+/mob/living/basic
+ /// whether the simple animal can be healed/damaged through reagents
+ var/reagent_health = TRUE
+
+/mob/living/basic/Initialize(mapload)
+ . = ..()
+ if(reagent_health)
+ create_reagents(1000, REAGENT_HOLDER_ALIVE)
+
+/mob/living/basic/Life(seconds_per_tick, times_fired)
+ . = ..()
+
+ if(!reagent_health)
+ return
+
+ if(!reagents)
+ return
+
+ if(stat == DEAD)
+ return
+
+ for(var/datum/reagent/reagents_within as anything in reagents.reagent_list)
+ if(istype(reagents_within, /datum/reagent/toxin))
+ var/datum/reagent/toxin/toxin_reagent = reagents_within
+ var/toxin_damage = round(toxin_reagent.toxpwr)
+ adjust_health(toxin_damage + 1)
+ reagents.remove_reagent(toxin_reagent.type, 0.5)
+ continue
+
+ if(istype(reagents_within, /datum/reagent/medicine))
+ adjust_health(-1)
+ reagents.remove_reagent(reagents_within.type, 0.5)
diff --git a/modular_skyrat/modules/ices_events/code/ICES_event_config.dm b/modular_skyrat/modules/ices_events/code/ICES_event_config.dm
index bd49fc1de17..c65aafe5da5 100644
--- a/modular_skyrat/modules/ices_events/code/ICES_event_config.dm
+++ b/modular_skyrat/modules/ices_events/code/ICES_event_config.dm
@@ -588,12 +588,6 @@
max_occurrences = 2
weight = VERY_HIGH_EVENT_FREQ
-/**
- * Wall Fungus
- */
-/datum/round_event_control/wall_fungus
- weight = MED_EVENT_FREQ
-
/**
* Wisdom Cow
*
diff --git a/modular_skyrat/modules/mapping/code/lavaland_ruin_code.dm b/modular_skyrat/modules/mapping/code/lavaland_ruin_code.dm
index c66faed0810..c2e667004c2 100644
--- a/modular_skyrat/modules/mapping/code/lavaland_ruin_code.dm
+++ b/modular_skyrat/modules/mapping/code/lavaland_ruin_code.dm
@@ -108,3 +108,15 @@
/obj/item/radio/headset/interdyne/comms
keyslot = new /obj/item/encryptionkey/headset_syndicate/interdyne
keyslot2 = new /obj/item/encryptionkey/syndicate
+
+//MOBS
+
+// hivelords that stand guard where they spawn
+/mob/living/basic/mining/hivelord/no_wander
+ ai_controller = /datum/ai_controller/basic_controller/hivelord/no_wander
+
+//MOB AI
+
+// same as a regular hivelord minus the idle walking
+/datum/ai_controller/basic_controller/hivelord/no_wander
+ idle_behavior = null
diff --git a/modular_skyrat/modules/modular_implants/code/nif_persistence.dm b/modular_skyrat/modules/modular_implants/code/nif_persistence.dm
index 1dc272c434e..fd24fd3b579 100644
--- a/modular_skyrat/modules/modular_implants/code/nif_persistence.dm
+++ b/modular_skyrat/modules/modular_implants/code/nif_persistence.dm
@@ -15,6 +15,8 @@
var/nif_is_calibrated
/// How many rewards points does the NIF have stored on it?
var/stored_rewards_points
+ /// A string containing programs that are transfered from one round to the next.
+ var/persistent_nifsofts
/// Saves the NIF data for a individual user.
/mob/living/carbon/human/proc/save_nif_data(datum/modular_persistence/persistence, remove_nif = FALSE)
@@ -51,14 +53,19 @@
persistence.stored_rewards_points = installed_nif.rewards_points
var/datum/component/nif_examine/examine_component = GetComponent(/datum/component/nif_examine)
-
persistence.nif_examine_text = examine_component?.nif_examine_text
+
+ var/persistent_nifsoft_paths = "" // We need to convert all of the paths in the list into a single string
for(var/datum/nifsoft/nifsoft as anything in installed_nif.loaded_nifsofts)
- if(!nifsoft.persistence)
+ if(nifsoft.persistence)
+ nifsoft.save_persistence_data(persistence)
+
+ if(!nifsoft.able_to_keep || !nifsoft.keep_installed)
continue
- nifsoft.save_persistence_data(persistence)
+ persistent_nifsoft_paths += "&[(nifsoft.type)]"
+ persistence.persistent_nifsofts = persistent_nifsoft_paths
/// Loads the NIF data for an individual user.
/mob/living/carbon/human/proc/load_nif_data(datum/modular_persistence/persistence)
@@ -74,6 +81,16 @@
new_nif.current_theme = persistence.nif_theme
new_nif.is_calibrated = persistence.nif_is_calibrated
new_nif.rewards_points = persistence.stored_rewards_points
+
+ var/list/persistent_nifsoft_paths = list()
+ for(var/text as anything in splittext(persistence.persistent_nifsofts, "&"))
+ var/datum/nifsoft/nifsoft_to_add = text2path(text)
+ if(!ispath(nifsoft_to_add, /datum/nifsoft) || !initial(nifsoft_to_add.able_to_keep))
+ continue
+
+ persistent_nifsoft_paths.Add(nifsoft_to_add)
+
+ new_nif.persistent_nifsofts = persistent_nifsoft_paths.Copy()
new_nif.Insert(src)
var/datum/component/nif_examine/examine_component = GetComponent(/datum/component/nif_examine)
diff --git a/modular_skyrat/modules/modular_implants/code/nifs.dm b/modular_skyrat/modules/modular_implants/code/nifs.dm
index 69c0a581c35..9dd1af28751 100644
--- a/modular_skyrat/modules/modular_implants/code/nifs.dm
+++ b/modular_skyrat/modules/modular_implants/code/nifs.dm
@@ -92,6 +92,8 @@
var/list/loaded_nifsofts = list()
///What programs come already installed on the NIF?
var/list/preinstalled_nifsofts = list(/datum/nifsoft/soul_poem)
+ ///What programs do we want to carry between rounds?
+ var/list/persistent_nifsofts = list()
///This shows up in the NIF settings screen as a way to ICly display lore.
var/manufacturer_notes = "There is no data currently avalible for this product."
@@ -147,8 +149,8 @@
linked_mob.AddComponent(/datum/component/nif_examine)
RegisterSignal(linked_mob, COMSIG_LIVING_DEATH, PROC_REF(damage_on_death))
- if(preinstalled_nifsofts)
- send_message("Loading preinstalled NIFSofts, please wait...")
+ if(preinstalled_nifsofts || persistent_nifsofts)
+ send_message("Loading preinstalled and stored NIFSofts, please wait...")
addtimer(CALLBACK(src, PROC_REF(install_preinstalled_nifsofts)), 3 SECONDS)
/obj/item/organ/internal/cyberimp/brain/nif/Remove(mob/living/carbon/organ_owner, special = FALSE)
@@ -174,6 +176,10 @@
for(var/datum/nifsoft/preinstalled_nifsoft as anything in preinstalled_nifsofts)
new preinstalled_nifsoft(src)
+ for(var/stored_nifsoft in persistent_nifsofts)
+ var/datum/nifsoft/new_stored_nifsoft = new stored_nifsoft(src)
+ new_stored_nifsoft.keep_installed = TRUE
+
return TRUE
/obj/item/organ/internal/cyberimp/brain/nif/process(seconds_per_tick)
diff --git a/modular_skyrat/modules/modular_implants/code/nifs_tgui.dm b/modular_skyrat/modules/modular_implants/code/nifs_tgui.dm
index 0423e28c830..6da74c6b89f 100644
--- a/modular_skyrat/modules/modular_implants/code/nifs_tgui.dm
+++ b/modular_skyrat/modules/modular_implants/code/nifs_tgui.dm
@@ -45,6 +45,8 @@
"active_cost" = nifsoft.active_cost,
"reference" = REF(nifsoft),
"ui_icon" = nifsoft.ui_icon,
+ "able_to_keep" = nifsoft.able_to_keep,
+ "keep_installed" = nifsoft.keep_installed,
)
data["loaded_nifsofts"] += list(nifsoft_data)
@@ -126,3 +128,11 @@
return FALSE
activated_nifsoft.activate()
+
+ if("toggle_keeping_nifsoft")
+ var/datum/nifsoft/nifsoft_to_keep = locate(params["nifsoft_to_keep"]) in loaded_nifsofts
+ if(!nifsoft_to_keep || !nifsoft_to_keep.able_to_keep)
+ return FALSE
+
+ nifsoft_to_keep.keep_installed = !nifsoft_to_keep.keep_installed
+ update_static_data_for_all_viewers()
diff --git a/modular_skyrat/modules/modular_implants/code/nifsoft_catalog.dm b/modular_skyrat/modules/modular_implants/code/nifsoft_catalog.dm
index aac352bab4c..6a3dde80e63 100644
--- a/modular_skyrat/modules/modular_implants/code/nifsoft_catalog.dm
+++ b/modular_skyrat/modules/modular_implants/code/nifsoft_catalog.dm
@@ -5,6 +5,7 @@ GLOBAL_LIST_INIT(purchasable_nifsofts, list(
/datum/nifsoft/summoner/dorms,
/datum/nifsoft/soul_poem,
/datum/nifsoft/soulcatcher,
+ /datum/nifsoft/summoner/book,
))
/datum/computer_file/program/nifsoft_downloader
@@ -79,6 +80,7 @@ GLOBAL_LIST_INIT(purchasable_nifsofts, list(
"category" = initial(buyable_nifsoft.buying_category),
"ui_icon" = initial(buyable_nifsoft.ui_icon),
"reference" = buyable_nifsoft,
+ "keepable" = initial(buyable_nifsoft.able_to_keep),
)
var/category = nifsoft_details["category"]
if(!(category in product_list))
diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts.dm b/modular_skyrat/modules/modular_implants/code/nifsofts.dm
index d7c382cfddb..1bf551866f5 100644
--- a/modular_skyrat/modules/modular_implants/code/nifsofts.dm
+++ b/modular_skyrat/modules/modular_implants/code/nifsofts.dm
@@ -47,6 +47,10 @@
var/rewards_points_eligible = TRUE
///Does the NIFSoft have anything that is saved cross-round?
var/persistence = FALSE
+ /// Is the NIFSoft something that we want to allow the user to keep?
+ var/able_to_keep = FALSE
+ /// Are we keeping the NIFSoft installed between rounds? This is decided by the user
+ var/keep_installed = FALSE
///Is it a lewd item?
var/lewd_nifsoft = FALSE
diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/book_summoner.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/book_summoner.dm
new file mode 100644
index 00000000000..954a56e9ff9
--- /dev/null
+++ b/modular_skyrat/modules/modular_implants/code/nifsofts/book_summoner.dm
@@ -0,0 +1,36 @@
+/obj/item/disk/nifsoft_uploader/summoner/book
+ name = "Grimoire Akasha"
+ loaded_nifsoft = /datum/nifsoft/summoner/book
+
+/datum/nifsoft/summoner/book
+ name = "Grimoire Akasha"
+ program_desc = "Grimoire Akasha is a fork of the Grimoire Caeruleam NIFSoft that is designed around giving the user access to various educational hardlight books. \
+ Due to its educational nature and miniscule size, Grimoire Akasha is typically provided for free at most NIFSoft marketplaces."
+ summonable_items = list()
+ purchase_price = 0 // This is a tool intended to help out newer players.
+ max_summoned_items = 2
+ buying_category = NIFSOFT_CATEGORY_INFORMATION
+ ui_icon = "book"
+
+/datum/nifsoft/summoner/book/New()
+ . = ..()
+ summonable_items += subtypesof(/obj/item/book/manual/wiki) //That's right! all of the manual books!
+
+/datum/nifsoft/summoner/book/apply_custom_properties(obj/item/book/generated_book)
+ if(!istype(generated_book))
+ return FALSE
+
+ generated_book.cannot_carve = TRUE
+ return TRUE
+
+// Need this code here so that we don't have people carving out the summoned books
+/obj/item/book
+ /// Is the parent book unable to be carved? TRUE prevents carving. By default this is unset
+ var/cannot_carve
+
+/obj/item/book/try_carve(obj/item/carving_item, mob/living/user, params)
+ if(cannot_carve)
+ balloon_alert(user, "unable to be carved!")
+ return FALSE
+
+ return ..()
diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/prop_summoner.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/prop_summoner.dm
index 5cd8a0443cb..aab1cc52b7a 100644
--- a/modular_skyrat/modules/modular_implants/code/nifsofts/prop_summoner.dm
+++ b/modular_skyrat/modules/modular_implants/code/nifsofts/prop_summoner.dm
@@ -16,6 +16,7 @@
activation_cost = 100 // Around 1/10th the energy of a standard NIF
buying_category = NIFSOFT_CATEGORY_FUN
ui_icon = "book-open"
+ able_to_keep = TRUE // These NIFSofts are mostly for comsetic/fun reasons anyways.
/// Does the resulting object have a holographic like filter appiled to it?
var/holographic_filter = TRUE
@@ -88,9 +89,17 @@
refund_activation_cost()
return FALSE
+ apply_custom_properties(new_item)
summoned_items += new_item
new_item.AddComponent(/datum/component/summoned_item, holographic_filter)
+/// This proc is called while an item is being summoned, use this to modifiy aspects of the item that aren't modified by the component.
+/datum/nifsoft/summoner/proc/apply_custom_properties(obj/item/target_item)
+ if(!target_item)
+ return FALSE
+
+ return TRUE
+
/datum/nifsoft/summoner/Destroy()
QDEL_LIST(summoned_items)
return ..()
diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/soulcatcher.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/soulcatcher.dm
index 9236a49f963..019ff546edc 100644
--- a/modular_skyrat/modules/modular_implants/code/nifsofts/soulcatcher.dm
+++ b/modular_skyrat/modules/modular_implants/code/nifsofts/soulcatcher.dm
@@ -7,6 +7,7 @@
program_desc = "The 'Soulcatcher' coreware is a near-complete upgrade of the nanomachine systems in a NIF, meant for one purpose; supposedly, channeling the dead. This upgrade, in truth, functions as a Resonance Simulation Device; an RSD for short, an instrument capable of hosting someone's consciousness, context or otherwise. 'Resonance', a term for the specific pattern of neural activity that gives way to someone's consciousness, was discovered in the early 2500s by researchers Yun-Seo Jin and Kamakshi Padmanabhan, coining what is now called 'Jin-Padmanabhan Resonance,' or 'JP/Soul Resonance.' This 'Resonance' gives off a sophont's consciousness, their sense of continuation, and their 'I am me.' This Resonance can vary in structure and 'strength' from person to person, and even change over someone's life. When the brain of a sophont undergoes death and stops neural activity, then Resonance dissipates entirely and lingering consciousness becomes essentially an echo, rapidly fading over time.\n\nThe earliest RSDs were massive machines, drawing incredible power and utilizing bleeding-edge, clunky software to 'play' someone's Resonance at 1:1 accuracy with their original brain. However, complications arose that are still being studied. Resonance is replicable and can be re-created artificially; however, like trying to duplicate genetic code, the capture needs to be extremely accurate, and rapidly put into place. Instruments such as RSDs are capable of picking up on lingering consciousness after the end of Resonance, and resuming it through artificial neural activity can give it strength to continue once more. RSDs such as Soulcatchers can only work at such a distance, otherwise running the risk of the Resonance essentially corrupting due to poor signal.\n\nIt is currently impossible to run Resonance in two places at once, because the same Resonance over two places experiences interference; like noise canceling headphones. Slimes and other gestalt consciousnesses can modulate their harmonics to a degree, bearing a partial disconnect and bringing themselves into constructive interference with similar harmonic signatures. A deepscan of the person's brain is necessary to give their consciousness 'context;' running their Resonance and capturing their consciousness alone results in a person with their same original intelligence, but zero memories or identity. These scans rapidly become outdated due to the growth of the brain, and it is prohibitively complex to store them in their entirety.\n\nThe first portable RSD, or Soulcatcher, was developed by the Spider Clan. These were initially designed for the captive interrogation of a person's consciousness without having to worry about the struggling of their body, and for dead or aging members of the mysterious group of orbital shinobi to be able to guide field operatives. These Soulcatchers are the main instrument to play Resonance, but recent advances in medical science have been leading to more. Occasionally, it is known for unusual sources of 'wild' Resonance, called Phantoms, to end up inside of the nearest Soulcatcher, a key finding its own lock; with a wide array of theories as to how these come into existence. Much as how some people intentionally become stable Engrams to achieve digital immortality, such as the witches of the Altspace Coven, it is possible for others to forcibly enter a Soulcatcher and act as a sort of Phantom by hacking their way in."
purchase_price = 150 //RP tool
persistence = TRUE
+ able_to_keep = TRUE
ui_icon = "ghost"
/// What is the linked soulcatcher datum used by this NIFSoft?
diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/bdsm_mask.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/bdsm_mask.dm
index 81cd35398b0..6a8f8a37c58 100644
--- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/bdsm_mask.dm
+++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/bdsm_mask.dm
@@ -27,11 +27,14 @@
actions_types = list(
/datum/action/item_action/toggle_breathcontrol,
/datum/action/item_action/mask_inhale,
+ /datum/action/item_action/toggle_gag,
)
var/list/moans = list("Mmmph...", "Hmmphh", "Mmmfhg", "Gmmmh...") // Phrases to be said when the player attempts to talk when speech modification / voicebox is enabled.
var/list/moans_alt = list("Mhgm...", "Hmmmp!...", "Gmmmhp!") // Power probability phrases to be said when talking.
var/moans_alt_probability = 5 // Probability for alternative sounds to play.
var/temp_check = TRUE //Used to check if user unconsious to prevent choking him until he wakes up
+ /// Does the gasmask impede the user's ability to talk?
+ var/speech_disabled
w_class = WEIGHT_CLASS_SMALL
modifies_speech = TRUE
flags_cover = MASKCOVERSMOUTH
@@ -53,6 +56,9 @@
update_icon()
/obj/item/clothing/mask/gas/bdsm_mask/handle_speech(datum/source, list/speech_args)
+ if(speech_disabled)
+ return
+
speech_args[SPEECH_MESSAGE] = pick((prob(moans_alt_probability) && LAZYLEN(moans_alt)) ? moans_alt : moans)
play_lewd_sound(loc, pick('modular_skyrat/modules/modular_items/lewd_items/sounds/under_moan_f1.ogg',
'modular_skyrat/modules/modular_items/lewd_items/sounds/under_moan_f2.ogg',
@@ -164,6 +170,15 @@
if(istype(mask))
mask.check()
+/datum/action/item_action/toggle_gag
+ name = "Toggle gag"
+ desc = "Toggles whether or not the wearer is able to speak."
+
+/datum/action/item_action/toggle_gag/Trigger(trigger_flags)
+ var/obj/item/clothing/mask/gas/bdsm_mask/mask = target
+ if(istype(mask))
+ mask.check_gag()
+
/datum/action/item_action/mask_inhale
name = "Inhale oxygen"
desc = "You must inhale oxygen!"
@@ -236,6 +251,19 @@
else
STOP_PROCESSING(SSobj, src)
+/obj/item/clothing/mask/gas/bdsm_mask/proc/check_gag(user)
+ var/mob/living/carbon/affected_carbon = user
+ if(src == affected_carbon.wear_mask)
+ to_chat(user, span_notice("You can't reach the gag switch!"))
+ else
+ toggle_gag(affected_carbon)
+
+/obj/item/clothing/mask/gas/bdsm_mask/proc/toggle_gag(user)
+ speech_disabled = !speech_disabled
+ to_chat(user, span_notice("You [speech_disabled ? "disable" : "enable"] the gag on the mask."))
+ update_mob_action_buttonss()
+ update_icon()
+
// Mask choke processor
/obj/item/clothing/mask/gas/bdsm_mask/process(seconds_per_tick)
var/mob/living/affected_mob = loc
diff --git a/modular_skyrat/modules/player_ranks/code/subsystem/player_ranks.dm b/modular_skyrat/modules/player_ranks/code/subsystem/player_ranks.dm
index 264d9f8bedc..6e724e44dbc 100644
--- a/modular_skyrat/modules/player_ranks/code/subsystem/player_ranks.dm
+++ b/modular_skyrat/modules/player_ranks/code/subsystem/player_ranks.dm
@@ -254,21 +254,37 @@ SUBSYSTEM_DEF(player_ranks)
* or in the legacy system.
*
* Arguments:
- * * admin - The admin making the rank change.
+ * * admin - The admin making the rank change. Can be a /client or a /datum/admins.
* * ckey - The ckey of the player you want to now possess that player rank.
* * rank_title - The title of the group you want to add the ckey to.
*/
-/datum/controller/subsystem/player_ranks/proc/add_player_to_group(client/admin, ckey, rank_title)
+/datum/controller/subsystem/player_ranks/proc/add_player_to_group(admin, ckey, rank_title)
if(IsAdminAdvancedProcCall())
return FALSE
if(!ckey || !admin || !rank_title)
+ stack_trace("Missing either ckey ([ckey || "*NULL*"]), admin ([admin || "*NULL*"]) or rank_title ([rank_title || "*NULL*"]) in add_player_to_group()! Fix this ASAP!")
return FALSE
- if(!check_rights_for(admin, R_PERMISSIONS))
- to_chat(admin, span_warning("You do not possess the permissions to do this."))
+ var/is_admin_client = istype(admin, /client)
+ var/client/admin_client = is_admin_client ? admin : null
+ // If it's not a client, then it should be an admins datum.
+ var/datum/admins/admin_holder = null
+ if(is_admin_client)
+ admin_holder = admin_client?.holder
+ else if(istype(admin, /datum/admins))
+ admin_holder = admin
+
+ if(!admin_holder)
+ return FALSE
+
+ if(!admin_holder.check_for_rights(R_PERMISSIONS))
+ if(is_admin_client)
+ to_chat(admin, span_warning("You do not possess the permissions to do this."))
+
return FALSE
+
rank_title = lowertext(rank_title)
var/datum/player_rank_controller/controller = get_controller_for_group(rank_title)
@@ -282,14 +298,16 @@ SUBSYSTEM_DEF(player_ranks)
var/already_in_config = controller.get_ckeys_for_legacy_save()
if(already_in_config[ckey])
- to_chat(admin, span_warning("\"[ckey]\" is already a [rank_title]!"))
+ if(is_admin_client)
+ to_chat(admin, span_warning("\"[ckey]\" is already a [rank_title]!"))
+
return FALSE
if(controller.should_use_legacy_system())
controller.add_player_legacy(ckey)
return TRUE
- return add_player_rank_sql(controller, ckey, admin.ckey)
+ return add_player_rank_sql(controller, ckey, admin_holder.target)
/**
@@ -325,19 +343,34 @@ SUBSYSTEM_DEF(player_ranks)
* or in the legacy system.
*
* Arguments:
- * * admin - The admin making the rank change.
+ * * admin - The admin making the rank change. Can be a /client or a /datum/admins.
* * ckey - The ckey of the player you want to no longer possess that player rank.
* * rank_title - The title of the group you want to remove the ckey from.
*/
-/datum/controller/subsystem/player_ranks/proc/remove_player_from_group(client/admin, ckey, rank_title)
+/datum/controller/subsystem/player_ranks/proc/remove_player_from_group(admin, ckey, rank_title)
if(IsAdminAdvancedProcCall())
return FALSE
if(!ckey || !admin || !rank_title)
+ stack_trace("Missing either ckey ([ckey || "*NULL*"]), admin ([admin || "*NULL*"]) or rank_title ([rank_title || "*NULL*"]) in remove_player_from_group()! Fix this ASAP!")
return FALSE
- if(!check_rights_for(admin, R_PERMISSIONS))
- to_chat(admin, span_warning("You do not possess the permissions to do this."))
+ var/is_admin_client = istype(admin, /client)
+ var/client/admin_client = is_admin_client ? admin : null
+ // If it's not a client, then it should be an admins datum.
+ var/datum/admins/admin_holder = null
+ if(is_admin_client)
+ admin_holder = admin_client?.holder
+ else if(istype(admin, /datum/admins))
+ admin_holder = admin
+
+ if(!admin_holder)
+ return FALSE
+
+ if(!admin_holder.check_for_rights(R_PERMISSIONS))
+ if(is_admin_client)
+ to_chat(admin, span_warning("You do not possess the permissions to do this."))
+
return FALSE
rank_title = lowertext(rank_title)
@@ -345,22 +378,16 @@ SUBSYSTEM_DEF(player_ranks)
var/datum/player_rank_controller/controller = get_controller_for_group(rank_title)
if(!controller)
- stack_trace("Invalid player rank \"[rank_title]\" supplied in add_player_to_group()!")
+ stack_trace("Invalid player rank \"[rank_title]\" supplied in remove_player_from_group()!")
return FALSE
ckey = ckey(ckey)
- var/already_in_config = controller.get_ckeys_for_legacy_save()
-
- if(!already_in_config[ckey])
- to_chat(admin, span_warning("\"[ckey]\" is already not a [rank_title]!"))
- return FALSE
-
if(controller.should_use_legacy_system())
controller.remove_player_legacy(ckey)
return TRUE
- return remove_player_rank_sql(controller, ckey, admin.ckey)
+ return remove_player_rank_sql(controller, ckey, admin_holder.target)
/**
diff --git a/modular_skyrat/modules/player_ranks/code/world_topic.dm b/modular_skyrat/modules/player_ranks/code/world_topic.dm
new file mode 100644
index 00000000000..086373fd33f
--- /dev/null
+++ b/modular_skyrat/modules/player_ranks/code/world_topic.dm
@@ -0,0 +1,67 @@
+
+/datum/world_topic/set_player_rank
+ keyword = "set_player_rank"
+ require_comms_key = TRUE
+
+/datum/world_topic/set_player_rank/Run(list/input)
+ . = list()
+
+ var/sender_discord_id = input["sender_discord_id"]
+
+ if(!sender_discord_id)
+ .["success"] = FALSE
+ .["message"] = "Invalid sender Discord ID, this should not be happening! Report this immediately!"
+ return
+
+ var/target_ckey = ckey(input["target_ckey"])
+
+ if(!target_ckey)
+ .["success"] = FALSE
+ .["message"] = "Invalid target ckey provided."
+ return
+
+ var/sender_ckey = ckey(SSdiscord.lookup_ckey(sender_discord_id))
+
+ if(!sender_ckey)
+ .["success"] = FALSE
+ .["message"] = "No ckey was found to be attached to the provided Discord account ID, **[sender_discord_id]**. Please verify your Discord account following the instructions of the in-game verb before trying this command again."
+ return
+
+ var/datum/admins/linked_admin_holder = GLOB.admin_datums[sender_ckey] || GLOB.deadmins[sender_ckey]
+
+ if(!linked_admin_holder)
+ .["success"] = FALSE
+ .["message"] = "No valid admin datum was found associated with the ckey associated to your Discord account."
+ return
+
+ if(!linked_admin_holder.check_for_rights(R_PERMISSIONS))
+ .["success"] = FALSE
+ .["message"] = "You do not possess the permissions to execute this command."
+ return
+
+ var/target_rank = input["target_rank"]
+
+ if(!target_rank)
+ .["success"] = FALSE
+ .["message"] = "Invalid target rank provided."
+ return
+
+ target_rank = capitalize(target_rank)
+
+ var/desired_rank_status = !!text2num(input["desired_rank_status"])
+
+ if(desired_rank_status)
+ var/result = SSplayer_ranks.add_player_to_group(linked_admin_holder, target_ckey, target_rank)
+
+ .["success"] = !!result
+ .["message"] = result ? "**[linked_admin_holder.target]** successfully added **[target_rank]** status to **[target_ckey]**." : "**[linked_admin_holder.target]** was unable to add **[target_rank]** status to **[target_ckey]**. Please verify that you entered their ckey correctly and that they did not already possess that status before trying again. Use the in-game verb to get more information if you keep on receiving this error."
+ message_admins(replacetext(.["message"], "*", ""))
+ return
+
+ else
+ var/result = SSplayer_ranks.remove_player_from_group(linked_admin_holder, target_ckey, target_rank)
+
+ .["success"] = !!result
+ .["message"] = result ? "**[linked_admin_holder.target]** successfully removed **[target_rank]** status from **[target_ckey]**." : "**[linked_admin_holder.target]** was unable to remove **[target_rank]** status from **[target_ckey]**. Please verify that you entered their ckey correctly and that they did possess that status before trying again. Use the in-game verb to get more information if you keep on receiving this error."
+ message_admins(replacetext(.["message"], "*", ""))
+ return
diff --git a/modular_skyrat/modules/primitive_catgirls/code/spawner.dm b/modular_skyrat/modules/primitive_catgirls/code/spawner.dm
index 8cb3f3234fe..5cbe1d682c0 100644
--- a/modular_skyrat/modules/primitive_catgirls/code/spawner.dm
+++ b/modular_skyrat/modules/primitive_catgirls/code/spawner.dm
@@ -66,8 +66,23 @@
/datum/team/primitive_catgirls
name = "Icewalkers"
+ member_name = "Icewalker"
show_roundend_report = FALSE
+/datum/team/primitive_catgirls/roundend_report()
+ var/list/report = list()
+
+ report += span_header("An Ice Walker Tribe inhabited the wastes...
")
+ if(length(members))
+ report += "The [member_name]s were:"
+ report += printplayerlist(members)
+ else
+ report += "But none of its members woke up!"
+
+ return "[report.Join("
")]
"
+
+// Antagonist datum
+
/datum/antagonist/primitive_catgirl
name = "\improper Icewalker"
job_rank = ROLE_LAVALAND // If you're ashwalker banned you should also not be playing this, other way around as well
diff --git a/modular_skyrat/modules/primitive_catgirls/code/species.dm b/modular_skyrat/modules/primitive_catgirls/code/species.dm
index 7bcaec865dd..586c7b22900 100644
--- a/modular_skyrat/modules/primitive_catgirls/code/species.dm
+++ b/modular_skyrat/modules/primitive_catgirls/code/species.dm
@@ -21,6 +21,7 @@
mutanttongue = /obj/item/organ/internal/tongue/cat/primitive
species_language_holder = /datum/language_holder/primitive_felinid
+ language_prefs_whitelist = list(/datum/language/primitive_catgirl)
bodytemp_normal = 270 // If a normal human gets hugged by one its gonna feel cold
bodytemp_heat_damage_limit = 283 // To them normal station atmos would be sweltering
diff --git a/modular_skyrat/modules/wall_fungus/code/wall_fungus_component.dm b/modular_skyrat/modules/wall_fungus/code/wall_fungus_component.dm
deleted file mode 100644
index 9c66677aaed..00000000000
--- a/modular_skyrat/modules/wall_fungus/code/wall_fungus_component.dm
+++ /dev/null
@@ -1,159 +0,0 @@
-#define FUNGUS_STAGE_ONE 1
-#define FUNGUS_STAGE_TWO 2
-#define FUNGUS_STAGE_THREE 3
-#define FUNGUS_STAGE_FOUR 4
-#define FUNGUS_STAGE_MAX 5
-
-/**
- * A wall eating mushroom.
- *
- * This mushroom spreads to walls and eats em up! It can be removed with a welder. If left unchecked it will eat the whole wall.
- */
-/datum/component/wall_fungus
- /// How far has the fungus progressed on the affected wall? Percentage.
- var/progression_percent = 0
- /// How many percent do we increase each subsystem fire?
- var/progression_step_amount = 0.5
- /// What stage are we at?
- var/progression_stage = FUNGUS_STAGE_ONE
- /// Our overlay icon file
- var/overlay_icon_file = 'modular_skyrat/modules/wall_fungus/icons/wall_fungus_overlay.dmi'
- /// How likely are we to spread to another wall?
- var/spread_chance = 1
- /// How far can we spread?
- var/spread_distance = 3 // Tiles
- /// How likely are we to drop a shroom upon destruction?
- var/drop_chance = 30
-
-/datum/component/wall_fungus/Initialize(override_progression_step_amount, override_spread_chance, override_spread_distance, override_drop_chance)
- if(!iswallturf(parent))
- return COMPONENT_INCOMPATIBLE
-
- // This stuff enables badminery.
- if(override_progression_step_amount)
- progression_step_amount = override_progression_step_amount
- if(override_spread_chance)
- spread_chance = override_progression_step_amount
- if(override_spread_distance)
- spread_distance = override_spread_distance
- if(override_drop_chance)
- drop_chance = override_drop_chance
-
- var/turf/closed/wall/parent_wall = parent
-
- RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(apply_fungus_overlay)) // We need to do this here so that the wall shows the infection immediately.
-
- parent_wall.update_icon(UPDATE_OVERLAYS)
-
- START_PROCESSING(SSobj, src)
-
-/datum/component/wall_fungus/RegisterWithParent()
- RegisterSignal(parent, COMSIG_ATOM_SECONDARY_TOOL_ACT(TOOL_WELDER), PROC_REF(secondary_tool_act))
- RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(examine))
- RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(on_attack_hand))
-
-/datum/component/wall_fungus/Destroy(force, silent)
- var/turf/closed/wall/parent_wall = parent
- STOP_PROCESSING(SSobj, src)
- UnregisterSignal(parent, list(COMSIG_ATOM_SECONDARY_TOOL_ACT(TOOL_WELDER), COMSIG_ATOM_EXAMINE, COMSIG_ATOM_UPDATE_OVERLAYS))
- parent_wall.update_icon(UPDATE_OVERLAYS)
- return ..()
-
-/datum/component/wall_fungus/process(seconds_per_tick)
- var/turf/closed/wall/parent_wall = parent
- if(prob(spread_chance * seconds_per_tick))
- spread_to_nearby_wall()
-
- if(progression_stage > FUNGUS_STAGE_MAX)
- collapse_parent_structure()
- return
-
- progression_percent += progression_step_amount * seconds_per_tick
-
- if(progression_percent >= 100)
- progression_percent = 0
- progression_stage++
- spread_to_nearby_wall()
- parent_wall.update_icon(UPDATE_OVERLAYS)
-
-/datum/component/wall_fungus/proc/on_attack_hand(datum/source, mob/living/user)
- SIGNAL_HANDLER
-
- if(progression_stage < FUNGUS_STAGE_THREE)
- return
-
- collapse_parent_structure()
-
-
-/// We kill the wall once we have progressed far enough.
-/datum/component/wall_fungus/proc/collapse_parent_structure()
- var/turf/closed/wall/parent_wall = parent
- STOP_PROCESSING(SSobj, src)
- parent_wall.balloon_alert_to_viewers("collapses!")
- parent_wall.dismantle_wall()
- qdel(src)
-
-/datum/component/wall_fungus/proc/spread_to_nearby_wall()
- var/turf/closed/wall/parent_wall = parent
- var/list/walls_to_pick_from = list()
- for(var/turf/closed/wall/iterating_wall in RANGE_TURFS(3, parent_wall))
- if(iterating_wall.GetComponent(/datum/component/wall_fungus))
- continue
-
- walls_to_pick_from += iterating_wall
-
- if(!length(walls_to_pick_from))
- return // sad times
-
- var/turf/closed/wall/picked_wall = pick(walls_to_pick_from)
-
- picked_wall.AddComponent(/datum/component/wall_fungus, progression_step_amount, spread_chance, spread_distance, drop_chance)
-
-/// Gives people an idea of how badly the wall is infected.
-/datum/component/wall_fungus/proc/examine(datum/source, mob/user, list/examine_list)
- SIGNAL_HANDLER
- var/turf/closed/wall/parent_wall = parent
- switch(progression_stage)
- if(FUNGUS_STAGE_ONE)
- examine_list += span_green("[parent_wall] is infected with some kind of fungus!")
- if(FUNGUS_STAGE_TWO)
- examine_list += span_green("[parent_wall] is infected with some kind of fungus, its structure weakened!")
- if(FUNGUS_STAGE_THREE)
- examine_list += span_green("[parent_wall] is infected with some kind of fungus, its structure seriously weakened!")
- if(FUNGUS_STAGE_THREE)
- examine_list += span_green("[parent_wall] is infected with some kind of fungus, its falling apart!")
- examine_list += span_green("Perhaps you could burn it off?")
-
-/datum/component/wall_fungus/proc/apply_fungus_overlay(atom/parent_atom, list/overlays)
- SIGNAL_HANDLER
- overlays += mutable_appearance(overlay_icon_file, "fungus_stage_[progression_stage]")
-
-/datum/component/wall_fungus/proc/secondary_tool_act(atom/source, mob/user, obj/item/item)
- SIGNAL_HANDLER
- INVOKE_ASYNC(src, PROC_REF(handle_tool_use), source, user, item)
- return COMPONENT_BLOCK_TOOL_ATTACK
-
-/// Handles removal of the fungus from a wall.
-/datum/component/wall_fungus/proc/handle_tool_use(atom/source, mob/user, obj/item/item)
- var/turf/closed/wall/parent_wall = parent
- switch(item.tool_behaviour)
- if(TOOL_WELDER)
- if(!item.tool_start_check(user, 1))
- return
-
- user.balloon_alert(user, "burning off fungus...")
-
- if(!item.use_tool(source, user, (1 * progression_stage) SECONDS, 1, volume = 100))
- return
-
- user.balloon_alert(user, "burned off fungus")
- if(prob(drop_chance))
- new /obj/item/food/grown/mushroom/wall(parent_wall)
- qdel(src)
-
-
-#undef FUNGUS_STAGE_ONE
-#undef FUNGUS_STAGE_TWO
-#undef FUNGUS_STAGE_THREE
-#undef FUNGUS_STAGE_FOUR
-#undef FUNGUS_STAGE_MAX
diff --git a/modular_skyrat/modules/wall_fungus/code/wall_fungus_event.dm b/modular_skyrat/modules/wall_fungus/code/wall_fungus_event.dm
deleted file mode 100644
index 564b9a9424e..00000000000
--- a/modular_skyrat/modules/wall_fungus/code/wall_fungus_event.dm
+++ /dev/null
@@ -1,29 +0,0 @@
-/datum/round_event_control/wall_fungus
- name = "Wall Fungus Outbreak"
- typepath = /datum/round_event/wall_fungus
- category = EVENT_CATEGORY_ENGINEERING
- max_occurrences = 2
- earliest_start = 30 MINUTES
- description = "A wall fungus will infest a random wall on the station, eating away at it. If left unchecked, it will spread to other walls and eventually destroy the station."
-
-/datum/round_event/wall_fungus/announce(fake)
- priority_announce("Harmful fungi detected on the station, station structures may be contaminated. Crew are advised to provide immediate response in [get_area(starting_wall)].", "Harmful Fungi", ANNOUNCER_FUNGI)
-
-/datum/round_event/wall_fungus
- announce_when = 180 EVENT_SECONDS
- announce_chance = 100
- fakeable = FALSE
- var/turf/closed/wall/starting_wall
-
-/datum/round_event/wall_fungus/start()
- var/list/possible_start_walls = list()
- var/starting_area = get_area(pick(GLOB.generic_maintenance_landmarks))
-
- for(var/turf/closed/wall/iterating_wall in starting_area)
- possible_start_walls += iterating_wall
-
- starting_wall = pick(possible_start_walls)
-
- starting_wall.AddComponent(/datum/component/wall_fungus)
-
- notify_ghosts("[starting_wall] has been infested with wall eating mushrooms!!", source = starting_wall, action = NOTIFY_JUMP, header = "Fungus Amongus!")
diff --git a/modular_skyrat/modules/wall_fungus/code/wall_mushroom.dm b/modular_skyrat/modules/wall_fungus/code/wall_mushroom.dm
deleted file mode 100644
index 71d99c164c6..00000000000
--- a/modular_skyrat/modules/wall_fungus/code/wall_mushroom.dm
+++ /dev/null
@@ -1,53 +0,0 @@
-// WALL EATING FUNGUS!!!!
-/obj/item/seeds/wall_mushroom
- name = "pack of wall destroying mycelium"
- desc = "This mycelium grows into something devastating."
- icon = 'modular_skyrat/master_files/icons/obj/hydroponics/seeds.dmi'
- icon_state = "seed-wallmushroom"
- species = "angel"
- plantname = "Wall Mushroom"
- product = /obj/item/food/grown/mushroom/wall
- lifespan = 50
- endurance = 35
- maturation = 12
- production = 5
- yield = 2
- potency = 35
- growthstages = 3
- genes = list(/datum/plant_gene/trait/plant_type/fungal_metabolism)
- growing_icon = 'modular_skyrat/master_files/icons/obj/hydroponics/growing.dmi'
- icon_grow = "wallmushroom-grow"
- icon_dead = "wallmushroom-dead"
- reagents_add = list(/datum/reagent/drug/mushroomhallucinogen = 0.04, /datum/reagent/toxin/amatoxin = 0.1, /datum/reagent/consumable/nutriment = 0.1)
- rarity = 30
- graft_gene = /datum/plant_gene/trait/plant_type/fungal_metabolism
-
-/obj/item/food/grown/mushroom/wall
- seed = /obj/item/seeds/wall_mushroom
- name = "wall mushroom"
- desc = "Wallosia Virosa: A wall eating mushroom!"
- icon = 'modular_skyrat/master_files/icons/obj/hydroponics/harvest.dmi'
- icon_state = "wallmushroom"
- wine_power = 60
-
-
-
-/obj/item/food/grown/mushroom/wall/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
- if(!iswallturf(target))
- return ..()
- var/turf/closed/wall/target_wall = target
- if(target_wall.GetComponent(/datum/component/wall_fungus))
- target_wall.balloon_alert(user, "already infested!")
- return ..()
- target_wall.balloon_alert(user, "planting...")
- if(do_after(user, 5 SECONDS, target_wall))
- target_wall.AddComponent(/datum/component/wall_fungus)
- target_wall.balloon_alert(user, "planted!")
- user.log_message("planted [name] on [target_wall.name].", LOG_ATTACK)
- qdel(src)
- return
- return ..()
-
-
-
-
diff --git a/modular_skyrat/modules/wall_fungus/icons/wall_fungus_overlay.dmi b/modular_skyrat/modules/wall_fungus/icons/wall_fungus_overlay.dmi
deleted file mode 100644
index 822d7ea9b29..00000000000
Binary files a/modular_skyrat/modules/wall_fungus/icons/wall_fungus_overlay.dmi and /dev/null differ
diff --git a/sound/creatures/attribution.txt b/sound/creatures/attribution.txt
index 1d2d543aa15..06d8361868c 100644
--- a/sound/creatures/attribution.txt
+++ b/sound/creatures/attribution.txt
@@ -1,8 +1,14 @@
-cow.ogg sound adapted from Benboncan on Freesound
+cow.ogg sound adapted from Benboncan on Freesound
https://freesound.org/people/Benboncan/sounds/58277/
pig1.ogg and pig2.ogg adapted from Jofae on Freesound
https://freesound.org/people/Jofae/sounds/352698/
sheep1, sheep2, and sheep3.ogg adapted from milkotz on Freesound
-https://freesound.org/people/milkotz/sounds/618865/
\ No newline at end of file
+https://freesound.org/people/milkotz/sounds/618865/
+
+snake_hissing1.ogg adapted from schreibsel on Freesound (CC 0)
+https://freesound.org/people/schreibsel/sounds/540162/
+
+snake_hissing2.ogg adapted from xoiziox on Freesound (CC 0)
+https://freesound.org/people/xoiziox/sounds/553374/
diff --git a/sound/creatures/bagawk.ogg b/sound/creatures/bagawk.ogg
new file mode 100644
index 00000000000..bfdce2da489
Binary files /dev/null and b/sound/creatures/bagawk.ogg differ
diff --git a/sound/creatures/chick_peep.ogg b/sound/creatures/chick_peep.ogg
new file mode 100644
index 00000000000..1e84d1d765f
Binary files /dev/null and b/sound/creatures/chick_peep.ogg differ
diff --git a/sound/creatures/chitter.ogg b/sound/creatures/chitter.ogg
new file mode 100644
index 00000000000..5b2a1443886
Binary files /dev/null and b/sound/creatures/chitter.ogg differ
diff --git a/sound/creatures/claw_click.ogg b/sound/creatures/claw_click.ogg
new file mode 100644
index 00000000000..965b4c3fa9f
Binary files /dev/null and b/sound/creatures/claw_click.ogg differ
diff --git a/sound/creatures/clucks.ogg b/sound/creatures/clucks.ogg
new file mode 100644
index 00000000000..176f46f866f
Binary files /dev/null and b/sound/creatures/clucks.ogg differ
diff --git a/sound/effects/mousesqueek.ogg b/sound/creatures/mousesqueek.ogg
similarity index 100%
rename from sound/effects/mousesqueek.ogg
rename to sound/creatures/mousesqueek.ogg
diff --git a/sound/creatures/pony/snort.ogg b/sound/creatures/pony/snort.ogg
index b023ddcf47c..0ea56ad957d 100644
Binary files a/sound/creatures/pony/snort.ogg and b/sound/creatures/pony/snort.ogg differ
diff --git a/sound/creatures/snake_hissing1.ogg b/sound/creatures/snake_hissing1.ogg
new file mode 100644
index 00000000000..52a37d764c4
Binary files /dev/null and b/sound/creatures/snake_hissing1.ogg differ
diff --git a/sound/creatures/snake_hissing2.ogg b/sound/creatures/snake_hissing2.ogg
new file mode 100644
index 00000000000..bd11b7fb5f0
Binary files /dev/null and b/sound/creatures/snake_hissing2.ogg differ
diff --git a/tgstation.dme b/tgstation.dme
index 40f533b939f..865654f09b7 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -149,6 +149,7 @@
#include "code\__DEFINES\mod.dm"
#include "code\__DEFINES\modular_computer.dm"
#include "code\__DEFINES\monkeys.dm"
+#include "code\__DEFINES\mood.dm"
#include "code\__DEFINES\move_force.dm"
#include "code\__DEFINES\movement.dm"
#include "code\__DEFINES\movespeed_modification.dm"
@@ -889,6 +890,7 @@
#include "code\datums\ai\bane\bane_controller.dm"
#include "code\datums\ai\bane\bane_subtrees.dm"
#include "code\datums\ai\basic_mobs\base_basic_controller.dm"
+#include "code\datums\ai\basic_mobs\generic_controllers.dm"
#include "code\datums\ai\basic_mobs\basic_ai_behaviors\basic_attacking.dm"
#include "code\datums\ai\basic_mobs\basic_ai_behaviors\climb_tree.dm"
#include "code\datums\ai\basic_mobs\basic_ai_behaviors\find_mineable_wall.dm"
@@ -1054,6 +1056,7 @@
#include "code\datums\components\customizable_reagent_holder.dm"
#include "code\datums\components\damage_aura.dm"
#include "code\datums\components\deadchat_control.dm"
+#include "code\datums\components\death_linked.dm"
#include "code\datums\components\dejavu.dm"
#include "code\datums\components\deployable.dm"
#include "code\datums\components\drift.dm"
@@ -1225,6 +1228,7 @@
#include "code\datums\components\crafting\misc.dm"
#include "code\datums\components\crafting\ranged_weapon.dm"
#include "code\datums\components\crafting\robot.dm"
+#include "code\datums\components\crafting\slapcrafting.dm"
#include "code\datums\components\crafting\structures.dm"
#include "code\datums\components\crafting\tailoring.dm"
#include "code\datums\components\crafting\tiles.dm"
@@ -1364,7 +1368,6 @@
#include "code\datums\elements\death_drops.dm"
#include "code\datums\elements\death_explosion.dm"
#include "code\datums\elements\death_gases.dm"
-#include "code\datums\elements\death_linked.dm"
#include "code\datums\elements\delete_on_drop.dm"
#include "code\datums\elements\deliver_first.dm"
#include "code\datums\elements\diggable.dm"
@@ -1733,6 +1736,7 @@
#include "code\datums\status_effects\debuffs\choke.dm"
#include "code\datums\status_effects\debuffs\confusion.dm"
#include "code\datums\status_effects\debuffs\cursed.dm"
+#include "code\datums\status_effects\debuffs\cyborg.dm"
#include "code\datums\status_effects\debuffs\debuffs.dm"
#include "code\datums\status_effects\debuffs\decloning.dm"
#include "code\datums\status_effects\debuffs\dizziness.dm"
@@ -2259,6 +2263,7 @@
#include "code\game\objects\items\circuitboards\machines\engine_circuitboards.dm"
#include "code\game\objects\items\circuitboards\machines\machine_circuitboards.dm"
#include "code\game\objects\items\devices\aicard.dm"
+#include "code\game\objects\items\devices\aicard_evil.dm"
#include "code\game\objects\items\devices\anomaly_neutralizer.dm"
#include "code\game\objects\items\devices\anomaly_releaser.dm"
#include "code\game\objects\items\devices\beacon.dm"
@@ -2761,6 +2766,7 @@
#include "code\modules\admin\verbs\fps.dm"
#include "code\modules\admin\verbs\getlogs.dm"
#include "code\modules\admin\verbs\ghost_pool_protection.dm"
+#include "code\modules\admin\verbs\grant_dna_infusion.dm"
#include "code\modules\admin\verbs\hiddenprints.dm"
#include "code\modules\admin\verbs\highlander_datum.dm"
#include "code\modules\admin\verbs\individual_logging.dm"
@@ -3249,6 +3255,7 @@
#include "code\modules\atmospherics\machinery\components\unary_devices\bluespace_sender.dm"
#include "code\modules\atmospherics\machinery\components\unary_devices\cryo.dm"
#include "code\modules\atmospherics\machinery\components\unary_devices\heat_exchanger.dm"
+#include "code\modules\atmospherics\machinery\components\unary_devices\machine_connector.dm"
#include "code\modules\atmospherics\machinery\components\unary_devices\outlet_injector.dm"
#include "code\modules\atmospherics\machinery\components\unary_devices\passive_vent.dm"
#include "code\modules\atmospherics\machinery\components\unary_devices\portables_connector.dm"
@@ -3457,6 +3464,7 @@
#include "code\modules\client\preferences\preferred_map.dm"
#include "code\modules\client\preferences\pride_pin.dm"
#include "code\modules\client\preferences\prisoner_crime.dm"
+#include "code\modules\client\preferences\prosthetic.dm"
#include "code\modules\client\preferences\random.dm"
#include "code\modules\client\preferences\runechat.dm"
#include "code\modules\client\preferences\scaling_method.dm"
@@ -4409,6 +4417,14 @@
#include "code\modules\mob\living\basic\lavaland\goliath\goliath_ai.dm"
#include "code\modules\mob\living\basic\lavaland\goliath\goliath_trophy.dm"
#include "code\modules\mob\living\basic\lavaland\goliath\tentacle.dm"
+#include "code\modules\mob\living\basic\lavaland\hivelord\hivelord.dm"
+#include "code\modules\mob\living\basic\lavaland\hivelord\hivelord_ai.dm"
+#include "code\modules\mob\living\basic\lavaland\hivelord\spawn_hivelord_brood.dm"
+#include "code\modules\mob\living\basic\lavaland\legion\legion.dm"
+#include "code\modules\mob\living\basic\lavaland\legion\legion_ai.dm"
+#include "code\modules\mob\living\basic\lavaland\legion\legion_brood.dm"
+#include "code\modules\mob\living\basic\lavaland\legion\legion_tumour.dm"
+#include "code\modules\mob\living\basic\lavaland\legion\spawn_legions.dm"
#include "code\modules\mob\living\basic\lavaland\lobstrosity\lobstrosity.dm"
#include "code\modules\mob\living\basic\lavaland\lobstrosity\lobstrosity_ai.dm"
#include "code\modules\mob\living\basic\lavaland\lobstrosity\lobstrosity_trophy.dm"
@@ -4439,6 +4455,7 @@
#include "code\modules\mob\living\basic\space_fauna\lightgeist.dm"
#include "code\modules\mob\living\basic\space_fauna\morph.dm"
#include "code\modules\mob\living\basic\space_fauna\mushroom.dm"
+#include "code\modules\mob\living\basic\space_fauna\robot_customer.dm"
#include "code\modules\mob\living\basic\space_fauna\spaceman.dm"
#include "code\modules\mob\living\basic\space_fauna\bear\_bear.dm"
#include "code\modules\mob\living\basic\space_fauna\bear\bear_ai_behavior.dm"
@@ -4474,6 +4491,8 @@
#include "code\modules\mob\living\basic\space_fauna\regal_rat\regal_rat.dm"
#include "code\modules\mob\living\basic\space_fauna\regal_rat\regal_rat_actions.dm"
#include "code\modules\mob\living\basic\space_fauna\regal_rat\regal_rat_ai.dm"
+#include "code\modules\mob\living\basic\space_fauna\snake\snake.dm"
+#include "code\modules\mob\living\basic\space_fauna\snake\snake_ai.dm"
#include "code\modules\mob\living\basic\space_fauna\spider\spider.dm"
#include "code\modules\mob\living\basic\space_fauna\spider\giant_spider\giant_spider_ai.dm"
#include "code\modules\mob\living\basic\space_fauna\spider\giant_spider\giant_spider_subtrees.dm"
@@ -4671,7 +4690,6 @@
#include "code\modules\mob\living\simple_animal\friendly\farm_animals.dm"
#include "code\modules\mob\living\simple_animal\friendly\gondola.dm"
#include "code\modules\mob\living\simple_animal\friendly\pet.dm"
-#include "code\modules\mob\living\simple_animal\friendly\robot_customer.dm"
#include "code\modules\mob\living\simple_animal\friendly\sloth.dm"
#include "code\modules\mob\living\simple_animal\friendly\drone\_drone.dm"
#include "code\modules\mob\living\simple_animal\friendly\drone\drone_say.dm"
@@ -4737,7 +4755,6 @@
#include "code\modules\mob\living\simple_animal\hostile\megafauna\wendigo.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\curse_blob.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\gutlunch.dm"
-#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\hivelord.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\ice_demon.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\mining_mobs.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\polarbear.dm"
@@ -4749,7 +4766,6 @@
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\elites\pandora.dm"
#include "code\modules\mob\living\simple_animal\hostile\retaliate\goose.dm"
#include "code\modules\mob\living\simple_animal\hostile\retaliate\retaliate.dm"
-#include "code\modules\mob\living\simple_animal\hostile\retaliate\snake.dm"
#include "code\modules\mob\living\simple_animal\hostile\retaliate\trader.dm"
#include "code\modules\mob\living\simple_animal\slime\death.dm"
#include "code\modules\mob\living\simple_animal\slime\emote.dm"
@@ -4766,6 +4782,7 @@
#include "code\modules\mob_spawn\corpses\nonhuman_corpses.dm"
#include "code\modules\mob_spawn\corpses\species_corpses.dm"
#include "code\modules\mob_spawn\ghost_roles\away_roles.dm"
+#include "code\modules\mob_spawn\ghost_roles\drone_roles.dm"
#include "code\modules\mob_spawn\ghost_roles\fugitive_hunter_roles.dm"
#include "code\modules\mob_spawn\ghost_roles\golem_roles.dm"
#include "code\modules\mob_spawn\ghost_roles\mining_roles.dm"
@@ -7087,6 +7104,7 @@
#include "modular_skyrat\modules\modular_implants\code\nifs_tgui.dm"
#include "modular_skyrat\modules\modular_implants\code\nifsoft_catalog.dm"
#include "modular_skyrat\modules\modular_implants\code\nifsofts.dm"
+#include "modular_skyrat\modules\modular_implants\code\nifsofts\book_summoner.dm"
#include "modular_skyrat\modules\modular_implants\code\nifsofts\dorms.dm"
#include "modular_skyrat\modules\modular_implants\code\nifsofts\hivemind.dm"
#include "modular_skyrat\modules\modular_implants\code\nifsofts\huds.dm"
@@ -7366,6 +7384,7 @@
#include "modular_skyrat\modules\pixel_shift\code\pixel_shift_component.dm"
#include "modular_skyrat\modules\pixel_shift\code\pixel_shift_keybind.dm"
#include "modular_skyrat\modules\pixel_shift\code\pixel_shift_mob.dm"
+#include "modular_skyrat\modules\player_ranks\code\world_topic.dm"
#include "modular_skyrat\modules\player_ranks\code\player_rank_controller\_player_rank_controller.dm"
#include "modular_skyrat\modules\player_ranks\code\player_rank_controller\donator_controller.dm"
#include "modular_skyrat\modules\player_ranks\code\player_rank_controller\mentor_controller.dm"
@@ -7572,9 +7591,6 @@
#include "modular_skyrat\modules\vox_sprites\code\head.dm"
#include "modular_skyrat\modules\vox_sprites\code\security.dm"
#include "modular_skyrat\modules\vox_sprites\code\sneakers.dm"
-#include "modular_skyrat\modules\wall_fungus\code\wall_fungus_component.dm"
-#include "modular_skyrat\modules\wall_fungus\code\wall_fungus_event.dm"
-#include "modular_skyrat\modules\wall_fungus\code\wall_mushroom.dm"
#include "modular_skyrat\modules\wargame_projectors\code\game_kit.dm"
#include "modular_skyrat\modules\wargame_projectors\code\holograms.dm"
#include "modular_skyrat\modules\wargame_projectors\code\projectors.dm"
diff --git a/tgui/packages/tgui/interfaces/CrewConsole.js b/tgui/packages/tgui/interfaces/CrewConsole.js
index 0c9a927c6f4..937ff9c1baf 100644
--- a/tgui/packages/tgui/interfaces/CrewConsole.js
+++ b/tgui/packages/tgui/interfaces/CrewConsole.js
@@ -1,18 +1,21 @@
import { sortBy } from 'common/collections';
import { useBackend } from '../backend';
-import { Box, Button, ColorBox, Section, Table } from '../components';
+import { Box, Button, Section, Table, Icon } from '../components';
import { COLORS } from '../constants';
import { Window } from '../layouts';
const HEALTH_COLOR_BY_LEVEL = [
'#17d568',
- '#2ecc71',
+ '#c4cf2d',
'#e67e22',
'#ed5100',
'#e74c3c',
- '#ed2814',
+ '#801308',
];
+const STAT_LIVING = 0;
+const STAT_DEAD = 4;
+
const jobIsHead = (jobId) => jobId % 10 === 0;
const jobToColor = (jobId) => {
@@ -40,10 +43,20 @@ const jobToColor = (jobId) => {
return COLORS.department.other;
};
-const healthToColor = (oxy, tox, burn, brute) => {
+const statToIcon = (life_status) => {
+ switch (life_status) {
+ case STAT_LIVING:
+ return 'heart';
+ case STAT_DEAD:
+ return 'skull';
+ }
+ return 'heartbeat';
+};
+
+const healthToAttribute = (oxy, tox, burn, brute, attributeList) => {
const healthSum = oxy + tox + burn + brute;
const level = Math.min(Math.max(Math.ceil(healthSum / 25), 0), 5);
- return HEALTH_COLOR_BY_LEVEL[level];
+ return attributeList[level];
};
const HealthStat = (props) => {
@@ -78,9 +91,11 @@ const CrewTable = (props, context) => {
Vitals
- Position
+
+ Position
+
{!!data.link_allowed && (
-
+
Tracking
)}
@@ -116,10 +131,22 @@ const CrewTableEntry = (props, context) => {
{assignment !== undefined ? ` (${assignment})` : ''}
- {life_status ? (
-
+ {oxydam !== undefined ? (
+
+ ) : life_status !== STAT_DEAD ? (
+
) : (
-
+
)}
@@ -133,13 +160,19 @@ const CrewTableEntry = (props, context) => {
{'/'}
- ) : life_status ? (
+ ) : life_status !== STAT_DEAD ? (
'Alive'
) : (
'Dead'
)}
- {area !== undefined ? area : 'N/A'}
+
+ {area !== undefined ? (
+ area
+ ) : (
+
+ )}
+
{!!link_allowed && (
- {oxydam !== undefined && life_status ? (
+ {oxydam !== undefined ? (
{
)}
size={1}
/>
- ) : life_status ? (
+ ) : life_status !== STAT_DEAD ? (
) : (
@@ -167,7 +167,7 @@ const CrewTableEntry = (props, context) => {
{'/'}
- ) : life_status ? (
+ ) : life_status !== STAT_DEAD ? (
'Alive'
) : (
'Dead'
diff --git a/tgui/packages/tgui/interfaces/NifPanel.js b/tgui/packages/tgui/interfaces/NifPanel.js
index 401f8b495d3..8e2d3160794 100644
--- a/tgui/packages/tgui/interfaces/NifPanel.js
+++ b/tgui/packages/tgui/interfaces/NifPanel.js
@@ -110,6 +110,29 @@ export const NifPanel = (props, context) => {
{nifsoft.desc}
+ {nifsoft.able_to_keep ? (
+
+
+
+ ) : (
+ <> >
+ )}
{
Purchasing this item will give you:{' '}
{product.rewards_points_rate * product.price} rewards points
+ {product.keepable ? (
+
+ This NIFSoft carries between shifts
+
+ ) : (
+ <> >
+ )}
+
))}
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic.tsx
new file mode 100644
index 00000000000..adbaefe90c8
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic.tsx
@@ -0,0 +1,6 @@
+import { FeatureChoiced, FeatureDropdownInput } from '../base';
+
+export const prosthetic: FeatureChoiced = {
+ name: 'Prosthetic',
+ component: FeatureDropdownInput,
+};
diff --git a/tgui/packages/tgui/interfaces/SecurityRecords/RecordView.tsx b/tgui/packages/tgui/interfaces/SecurityRecords/RecordView.tsx
index 5e39c743ec3..851425dadfd 100644
--- a/tgui/packages/tgui/interfaces/SecurityRecords/RecordView.tsx
+++ b/tgui/packages/tgui/interfaces/SecurityRecords/RecordView.tsx
@@ -56,6 +56,7 @@ const RecordInfo = (props, context) => {
rank,
species,
wanted_status,
+ voice,
// SKYRAT EDIT START - RP Records
past_general_records,
past_security_records,
@@ -172,6 +173,9 @@ const RecordInfo = (props, context) => {
text={fingerprint}
/>
+
+
+
{
integrity,
integrity_factors,
internal_energy,
+ internal_energy_coefficient,
+ internal_energy_unit,
internal_energy_factors,
- zap_multiplier,
- zap_multiplier_factors,
+ zap_transmission,
+ zap_transmission_coefficient,
+ zap_transmission_unit,
+ zap_transmission_factors,
temp_limit,
temp_limit_factors,
waste_multiplier,
@@ -166,19 +175,20 @@ export const SupermatterContent = (props: SupermatterProps, context) => {
average: [5000, 7000],
bad: [7000, Infinity],
}}>
- {toFixed(internal_energy) + ' MeV/cm3'}
+ {toFixed(internal_energy_coefficient, 3) +
+ internal_energy_unit}
}
detail={
!!internal_energy_factors.length && (
- {internal_energy_factors.map(({ name, amount }) => (
+ {internal_energy_factors.map(({ name, amount, unit }) => (
0 ? 'green' : 'red'}>
- {toFixed(amount, 2) + ' MeV/cm3'}
+ {toFixed(amount, 3) + unit}
))}
@@ -187,28 +197,30 @@ export const SupermatterContent = (props: SupermatterProps, context) => {
}
/>
- {toFixed(zap_multiplier, 2) + ' x'}
+ {toFixed(zap_transmission_coefficient, 2) +
+ zap_transmission_unit}
}
detail={
- !!zap_multiplier_factors.length && (
+ !!zap_transmission_factors.length && (
- {zap_multiplier_factors.map(({ name, amount }) => (
+ {zap_transmission_factors.map(({ name, amount, unit }) => (
0 ? 'green' : 'red'}>
- {toFixed(amount, 2) + ' x'}
+ {toFixed(amount, 2) + unit}
))}
@@ -356,8 +368,8 @@ export const SupermatterContent = (props: SupermatterProps, context) => {
: 'red'
}>
{effect.amount > 0
- ? '+' + effect.amount * 100 + '%'
- : effect.amount * 100 + '%'}
+ ? '+' + effect.amount + effect.unit
+ : effect.amount + effect.unit}
)
)}
diff --git a/tools/UpdatePaths/Scripts/78273_cryo_removed_atmosmachinery_path.txt b/tools/UpdatePaths/Scripts/78273_cryo_removed_atmosmachinery_path.txt
new file mode 100644
index 00000000000..6d8a2c54f38
--- /dev/null
+++ b/tools/UpdatePaths/Scripts/78273_cryo_removed_atmosmachinery_path.txt
@@ -0,0 +1,2 @@
+#Updates cryo cells pathing by removing the atmosmachinery path
+/obj/machinery/atmospherics/components/unary/cryo_cell : /obj/machinery/cryo_cell{@OLD}
diff --git a/tools/UpdatePaths/Scripts/78612_simple_to_basic_snakes.txt b/tools/UpdatePaths/Scripts/78612_simple_to_basic_snakes.txt
new file mode 100644
index 00000000000..083fc74e24f
--- /dev/null
+++ b/tools/UpdatePaths/Scripts/78612_simple_to_basic_snakes.txt
@@ -0,0 +1 @@
+/mob/living/simple_animal/hostile/retaliate/snake : /mob/living/basic/snake{@OLD}
diff --git a/tools/UpdatePaths/Scripts/78624_simple_to_basic_legion.txt b/tools/UpdatePaths/Scripts/78624_simple_to_basic_legion.txt
new file mode 100644
index 00000000000..bf397a83bb2
--- /dev/null
+++ b/tools/UpdatePaths/Scripts/78624_simple_to_basic_legion.txt
@@ -0,0 +1,3 @@
+/mob/living/simple_animal/hostile/asteroid/hivelord : /mob/living/basic/mining/hivelord{@OLD}
+/mob/living/simple_animal/hostile/big_legion : /mob/living/basic/mining/legion/big{@OLD}
+/mob/living/simple_animal/hostile/asteroid/hivelord/legion/@SUBTYPES : /mob/living/basic/mining/legion/@SUBTYPES{@OLD}
diff --git a/tools/tts/tts-api/off1.wav b/tools/tts/tts-api/off1.wav
new file mode 100644
index 00000000000..9c509139f5d
Binary files /dev/null and b/tools/tts/tts-api/off1.wav differ
diff --git a/tools/tts/tts-api/off2.wav b/tools/tts/tts-api/off2.wav
new file mode 100644
index 00000000000..e84221070a5
Binary files /dev/null and b/tools/tts/tts-api/off2.wav differ
diff --git a/tools/tts/tts-api/off3.wav b/tools/tts/tts-api/off3.wav
new file mode 100644
index 00000000000..ca1f9b377c3
Binary files /dev/null and b/tools/tts/tts-api/off3.wav differ
diff --git a/tools/tts/tts-api/off4.wav b/tools/tts/tts-api/off4.wav
new file mode 100644
index 00000000000..6831bc1bcde
Binary files /dev/null and b/tools/tts/tts-api/off4.wav differ
diff --git a/tools/tts/tts-api/on1.wav b/tools/tts/tts-api/on1.wav
new file mode 100644
index 00000000000..5137fa195a7
Binary files /dev/null and b/tools/tts/tts-api/on1.wav differ
diff --git a/tools/tts/tts-api/on2.wav b/tools/tts/tts-api/on2.wav
new file mode 100644
index 00000000000..d0178cae432
Binary files /dev/null and b/tools/tts/tts-api/on2.wav differ
diff --git a/tools/tts/tts-api/tts-api.py b/tools/tts/tts-api/tts-api.py
index 27f56e5488b..e1a5880da5b 100644
--- a/tools/tts/tts-api/tts-api.py
+++ b/tools/tts/tts-api/tts-api.py
@@ -4,11 +4,18 @@
import subprocess
import requests
import re
+import pysbd
+import pydub
+import string
+import random
+import json
from flask import Flask, request, send_file, abort, make_response
-
+tts_sample_rate = 40000 # Set to 40000 if you're using RVC, or whatever sample rate your endpoint is going to send the audio in.
app = Flask(__name__)
-
-authorization_token = os.getenv("TTS_AUTHORIZATION_TOKEN", "coolio")
+segmenter = pysbd.Segmenter(language="en", clean=True)
+radio_starts = ["./on1.wav", "./on2.wav"]
+radio_ends = ["./off1.wav", "./off2.wav", "./off3.wav", "./off4.wav"]
+authorization_token = os.getenv("TTS_AUTHORIZATION_TOKEN", "vote_goof_2024")
def hhmmss_to_seconds(string):
new_time = 0
separated_times = string.split(":")
@@ -17,29 +24,46 @@ def hhmmss_to_seconds(string):
new_time += float(separated_times[2])
return new_time
-def text_to_speech_handler(endpoint, voice, text, filter_complex, pitch, silicon = False):
+def text_to_speech_handler(endpoint, voice, text, filter_complex, pitch, special_filters = []):
filter_complex = filter_complex.replace("\"", "")
- response = requests.get(f"http://tts-container:5003/" + endpoint, json={ 'text': text, 'voice': voice, 'pitch': pitch })
- if response.status_code != 200:
- abort(500)
-
+ data_bytes = io.BytesIO()
+ final_audio = pydub.AudioSegment.empty()
+
+ for sentence in segmenter.segment(text):
+ response = requests.get(f"http://127.0.0.1:5003/" + endpoint, json={ 'text': sentence, 'voice': voice, 'pitch': pitch })
+ if response.status_code != 200:
+ abort(500)
+ sentence_audio = pydub.AudioSegment.from_file(io.BytesIO(response.content), "wav")
+ sentence_silence = pydub.AudioSegment.silent(250, 40000)
+ sentence_audio += sentence_silence
+ final_audio += sentence_audio
+ # ""Goldman-Eisler (1968) determined that typical speakers paused for an average of 250 milliseconds (ms), with a range from 150 to 400 ms.""
+ # (https://scholarsarchive.byu.edu/cgi/viewcontent.cgi?article=10153&context=etd)
+ final_audio.export(data_bytes, format="wav")
+ filter_complex = filter_complex.replace("%SAMPLE_RATE%", str(tts_sample_rate))
ffmpeg_result = None
if filter_complex != "":
- ffmpeg_result = subprocess.run(["ffmpeg", "-f", "wav", "-i", "pipe:0", "-filter_complex", filter_complex, "-c:a", "libvorbis", "-b:a", "64k", "-f", "ogg", "pipe:1"], input=response.content, capture_output = True)
+ ffmpeg_result = subprocess.run(["ffmpeg", "-f", "wav", "-i", "pipe:0", "-filter_complex", filter_complex, "-c:a", "libvorbis", "-b:a", "64k", "-f", "ogg", "pipe:1"], input=data_bytes.read(), capture_output = True)
else:
- if silicon:
- ffmpeg_result = subprocess.run(["ffmpeg", "-f", "wav", "-i", "pipe:0", "-i", "./SynthImpulse.wav", "-i", "./RoomImpulse.wav", "-filter_complex", "[0] aresample=44100 [re_1]; [re_1] apad=pad_dur=2 [in_1]; [in_1] asplit=2 [in_1_1] [in_1_2]; [in_1_1] [1] afir=dry=10:wet=10 [reverb_1]; [in_1_2] [reverb_1] amix=inputs=2:weights=8 1 [mix_1]; [mix_1] asplit=2 [mix_1_1] [mix_1_2]; [mix_1_1] [2] afir=dry=1:wet=1 [reverb_2]; [mix_1_2] [reverb_2] amix=inputs=2:weights=10 1 [mix_2]; [mix_2] equalizer=f=7710:t=q:w=0.6:g=-6,equalizer=f=33:t=q:w=0.44:g=-10 [out]; [out] alimiter=level_in=1:level_out=1:limit=0.5:attack=5:release=20:level=disabled", "-c:a", "libvorbis", "-b:a", "64k", "-f", "ogg", "pipe:1"], input=response.content, capture_output = True)
+ if "silicon" in special_filters:
+ ffmpeg_result = subprocess.run(["ffmpeg", "-f", "wav", "-i", "pipe:0", "-i", "./SynthImpulse.wav", "-i", "./RoomImpulse.wav", "-filter_complex", "[0] aresample=44100 [re_1]; [re_1] apad=pad_dur=2 [in_1]; [in_1] asplit=2 [in_1_1] [in_1_2]; [in_1_1] [1] afir=dry=10:wet=10 [reverb_1]; [in_1_2] [reverb_1] amix=inputs=2:weights=8 1 [mix_1]; [mix_1] asplit=2 [mix_1_1] [mix_1_2]; [mix_1_1] [2] afir=dry=1:wet=1 [reverb_2]; [mix_1_2] [reverb_2] amix=inputs=2:weights=10 1 [mix_2]; [mix_2] equalizer=f=7710:t=q:w=0.6:g=-6,equalizer=f=33:t=q:w=0.44:g=-10 [out]; [out] alimiter=level_in=1:level_out=1:limit=0.5:attack=5:release=20:level=disabled", "-c:a", "libvorbis", "-b:a", "64k", "-f", "ogg", "pipe:1"], input=data_bytes.read(), capture_output = True)
else:
- ffmpeg_result = subprocess.run(["ffmpeg", "-f", "wav", "-i", "pipe:0", "-c:a", "libvorbis", "-b:a", "64k", "-f", "ogg", "pipe:1"], input=response.content, capture_output = True)
+ ffmpeg_result = subprocess.run(["ffmpeg", "-f", "wav", "-i", "pipe:0", "-c:a", "libvorbis", "-b:a", "64k", "-f", "ogg", "pipe:1"], input= data_bytes.read(), capture_output = True)
ffmpeg_metadata_output = ffmpeg_result.stderr.decode()
print(f"ffmpeg result size: {len(ffmpeg_result.stdout)} stderr = \n{ffmpeg_metadata_output}")
-
-
+ export_audio = io.BytesIO(ffmpeg_result.stdout)
+ if "radio" in special_filters:
+ radio_audio = pydub.AudioSegment.from_file(random.choice(radio_starts), "wav")
+ radio_audio += pydub.AudioSegment.from_file(io.BytesIO(ffmpeg_result.stdout), "ogg")
+ radio_audio += pydub.AudioSegment.from_file(random.choice(radio_ends), "wav")
+ new_data_bytes = io.BytesIO()
+ radio_audio.export(new_data_bytes, format="ogg")
+ export_audio = io.BytesIO(new_data_bytes.getvalue())
matched_length = re.search(r"time=([0-9:\\.]+)", ffmpeg_metadata_output)
hh_mm_ss = matched_length.group(1)
length = hhmmss_to_seconds(hh_mm_ss)
- response = send_file(io.BytesIO(ffmpeg_result.stdout), as_attachment=True, download_name='identifier.ogg', mimetype="audio/ogg")
+ response = send_file(export_audio, as_attachment=True, download_name='identifier.ogg', mimetype="audio/ogg")
response.headers['audio-length'] = length
return response
@@ -51,12 +75,15 @@ def text_to_speech_normal():
voice = request.args.get("voice", '')
text = request.json.get("text", '')
pitch = request.args.get("pitch", '')
- silicon = request.args.get("silicon", '')
+ special_filters = request.args.get("special_filters", '')
if pitch == "":
pitch = "0"
+ silicon = request.args.get("silicon", '')
+ if silicon:
+ special_filters = ["silicon"]
filter_complex = request.args.get("filter", '')
- return text_to_speech_handler("generate-tts", voice, text, filter_complex, pitch, bool(silicon))
+ return text_to_speech_handler("generate-tts", voice, text, filter_complex, pitch, special_filters)
@app.route("/tts-blips")
def text_to_speech_blips():
@@ -66,12 +93,13 @@ def text_to_speech_blips():
voice = request.args.get("voice", '')
text = request.json.get("text", '')
pitch = request.args.get("pitch", '')
- silicon = request.args.get("silicon", '')
+ special_filters = request.args.get("special_filters", '')
if pitch == "":
pitch = "0"
+ special_filters = special_filters.split("|")
filter_complex = request.args.get("filter", '')
- return text_to_speech_handler("generate-tts-blips", voice, text, filter_complex, pitch, bool(silicon))
+ return text_to_speech_handler("generate-tts-blips", voice, text, filter_complex, pitch, special_filters)
@@ -80,7 +108,7 @@ def voices_list():
if authorization_token != request.headers.get("Authorization", ""):
abort(401)
- response = requests.get(f"http://tts-container:5003/tts-voices")
+ response = requests.get(f"http://127.0.0.1:5003/tts-voices")
return response.content
@app.route("/health-check")
@@ -93,7 +121,7 @@ def pitch_available():
if authorization_token != request.headers.get("Authorization", ""):
abort(401)
- response = requests.get(f"http://tts-container:5003/pitch-available")
+ response = requests.get(f"http://127.0.0.1:5003/pitch-available")
if response.status_code != 200:
abort(500)
return make_response("Pitch available", 200)